2012-05-06 6 views
19

レールの使い慣れたヘルパーを使用したいが、少し変更された機能を使用したい。私はそれを参照してください方法は、私のような何かを行うことができるようにしたい:レールのヘルパーモジュールの再オープン:オリジナルへのアクセスでレールヘルパーをオーバーライド

  1. モンキーパッチング:

    module AwesomeHelper 
        #... create alias of stylesheet_link_tag to old_stylesheet_link_tag 
        def stylesheet_link_tag(*args) 
        if @be_awesome 
         awesome_stylesheet_link_tag *args 
        else 
         old_stylesheet_link_tag *args 
        end 
        end 
    end 
    

    私はそれを見る方法を、私は3つのオプションを持っています。レールチームがヘルパーモジュールの名前を変更した場合、私のコードは脆弱の原因になります。克服できないものではありませんが、理想的ではありません。

  2. 別のメソッド名を使用してください:共通のレールインターフェイスに固執しようとすると、私の没落につながる可能性があります。私の変更は他の開発者にとって混乱の原因になる可能性があります
  3. デタッチ方法(新規):これがうまくいくかどうか、または1と同じ欠点があるかどうかはわかりません。出発点。

ここで問題になるのは、これらの準最適解のうちの1つに固執しているのですか、それとも私が考慮していない別の方法がありますか?オプション3に行くと、レールヘルパーモジュールに直接アドレスを指定しなくてもそれを行う方法はありますか?

(注:私は、コンテキストを削除した、それは質問には何も加えないよう)

答えて

30

リストされているオプションよりも優れた方法があります。ただ、superを使用します。

module AwesomeHelper 
    def stylesheet_link_tag(*sources) 
    if @be_awesome 
     awesome_stylesheet_link_tag *sources 
    else 
     super 
    end 
    end 
end 

はAwesomeHelperでstylesheet_link_tagをオーバーライドそれはActionView::Helpers::AssetTagHelperを打つ前にstylesheet_link_tagが呼び出されたときに、次のことを確認しますが、Rubyはメソッド・ルックアップ・パスで、それが発生します。 @be_awesometrueの場合、すぐに処理を停止し、そうでない場合は、かっこなしのsuperの呼び出しは、透過的にすべての引数をRails実装に渡します。このようにして、Railsのコアチームが物事をあなたの周りに動かす心配はありません!

+0

あなたが知っていることは...それはとても狂った明白です、私は私の頭脳を動かして私はそれがうまくいかないと思った!私は今夜​​それを試してみるつもりです、もしそれがうまくいくなら、私はおそらくレンガの壁を含む私の脳で深刻な言葉を持つでしょう。あなたの答えを受け入れた後、もちろん:D – user208769

+1

@ user208769 Hehehe。それは素晴らしいです。私が理解しているように、この方法でメソッドをオーバーライドすることは、どのような状況でも一般に望ましい方法です。 [Class#ancestors](http://ruby-doc.org/core-1.9.3/Module.html#method-i-ancestors)は、ハイジャックメソッドへのメソッドルックアップパスの良い場所を見つけるのに本当に役立ちますディスパッチ(または最適化を行うためにオーバーライドされたカスタムモジュールが含まれている必要がある場所)。 – Cade

+0

何ですか? :)あなたは冗談を言う必要があります!これは巨大な問題です! AssetTagHelperを含むあらゆるクラスにヘルパーを含める必要があります。時間が飛んで、あなたや他の誰かがあなたのパッチが含まれることを忘れることができます。あなたは単にAssetTagHelperを組み込み、なぜ私のサイトが異なって見えるのか不思議に思うようになります。あなたとパッチメーカーが同じ人であればいいですね。しかし、もしそうでなければ? – jdoe

6

私はこの宝石を使用していないので、私はより一般的な方法であなたにお答えします。

link_toヘルパーへの通話をログに記録したいとしましょう(たとえば、実際の例ですが、そのアイデアを示しています)。 APIを見ると、link_toActionView::Helpers::UrlHelperモジュール内にあることを理解できます。だから、あなたはあなたの中にいくつかのファイルを作成し、次の内容でconfig/initializersディレクトリは、言う:

# like in config/initializers/link_to_log.rb 
module ActionView::Helpers::UrlHelper 

    def link_to_with_log(*args, &block) 
     logger.info '**** LINK_TO CALL ***' 
     link_to_without_log(*args, &block) # calling the original helper 
    end 

    alias_method_chain :link_to, :log 
end 

この機能のコア - alias_method_chain(クリック可能)。メソッドxxx_with_featureを定義した後で使用してください。

+0

うん、このアプローチは、私が「猿特定のレールをパッチモジュール」によって意味したものだった - うまく動作しますが、レールのコアは、そのモジュール名、私のコードの区切りを変更した場合。これは大きな問題ではないかもしれませんが、私は他の解決方法があるかどうかを知りたいのです。それは、alias_method_chainについて忘れてしまった、それを思い出させてくれてありがとう! – user208769

+0

P.S:宝石の例を削除する質問が更新されました。うまくいけば、このレイアウトはあまり混乱しないでしょう!ありがとうございました。 – user208769

+0

リスクは常にそこにあります! 'alias_method_chain'について心配するならば、それはバージョン1.4.0(2007年)以降存在するべきではありません。あなたのプログラムの他の部分について心配する場合は、まともなテストの範囲を確保してください。 – jdoe

2

私は実際にあなたのオプション#2を考えて、呼び出し側に明らかな方法でrailsメソッドの動作をオーバーライドすることをお勧めします。

あなたの新しいメソッドはawesome_stylesheet_link_tagと呼ばれ、他のRailsの開発者があなたのコードを読んで、「リンクタグについては何がすごいですか?」という質問をすることができます。

より小さな変更では、オーバーライドを実行できますが、:awesome => trueを引数として渡すので、少なくとも何かが起こっているという手掛かりがあります。

stylesheet_link_tagのような広く使用されているメソッドの動作を変更すると、何も不要なところで誤解を招く可能性があります。

+0

ありがとうございました。通常、私は同意しますが、この特定のケースでは、一貫性が正当だと思います。wicked_pdfを使用し、まったく同じコードでPDFまたはWebページを生成するには、これを行います。デフォルトではwicked_pdfはあなたの言うとおりに(wicked_pdf_stylesheet_link_tag)、それは私にとって多すぎる反復を必要とします。私は、PDFを生成していると機能が変わることが予想されます。しかし、あなたは良い点を、そして便利なヒントを作るので、ありがとう。 – user208769

4

alias_methodを使用してみてください:

module AwesomeHelper 
    alias_method :original_stylesheet_link_tag, :stylesheet_link_tag 

    def stylesheet_link_tag(*sources) 
    if @be_awesome 
     awesome_stylesheet_link_tag *sources 
    else 
     original_stylesheet_link_tag *sources 
    end 
    end 
end 
関連する問題