3

少しわかりづらいalias_method/ alias_method_chain。私は次のコードを持っています:

module ActionView::Helpers
  module FormHelper

    alias_method :form_for_without_cherries, :form_for

    def form_for(record, options = {}, &proc)
      output = 'with a cherry on top'.html_safe
      output.safe_concat form_for_without_cherries(record, options = {}, &proc)
    end
  end
end

form_forこれは、私が望んでいることを正確に実行します。呼び出しの先頭に「チェリーを上に」を追加します。

しかし、私の理解では、これはいくつかの理由で適切なコードではありません。まず、他のオーバーライドにチェーンされないform_for(?)ため、「さらに別のチェリーを上に」追加する2番目のform_forメソッドを作成した場合、表示されません。そして第二に、そして、alias_methodちょっとalias_method_chain時代遅れの解決策であり、self.included代わりにモジュールを使用して送信する必要があります。

self.includedしかし、このメソッドを呼び出すことはできませんform_for。親メソッドを呼び出し続けるだけです。これが私が試していることです:

module CherryForm
  def self.included(base)
    base.extend(self)
  end

  def form_for(record, options = {}, &proc)
    output = 'with a cherry on top'.html_safe
    output.safe_concat super(record, options = {}, &proc)
  end 
end

ActionView::Helpers::FormHelper.send(:include, CherryForm)

私の上記の解決策は機能しますが、それが間違ったやり方であるのではないかと疑っています。ルビーのベテランがこれを行うためのよりエレガントな方法を教えてくれるなら-そして/または2番目の解決策が呼ばれていない理由-私は感謝するでしょう。

4

1 に答える 1

4

何かをモンキーパッチするときは、継承するスーパーがないため、メソッドを再定義する必要があります(したがって、2番目のコードの抜粋を使用することはできません)。

現在のメソッド実装をコピーして独自の実装を追加することは問題を引き起こすだけなので、これがalias_methodの出番です。

alias_method :form_for_without_cherries, :form_for

実際には、元のメソッドのクローンが作成され、superの代わりに使用できます。モンキーパッチをチェーンできないという事実はバグではなく、機能です。

rails alias_method_chainメソッドは実際に非推奨になりましたが、それは最初から悪い考えだったからです。ただし、alias_methodは純粋なrubyメソッドであり、正しく使用すると、コードにモンキーパッチを適用するエレガントな方法を提供できます。そのため、すぐになくなることはないと確信しています。

于 2012-04-05T20:08:33.773 に答える