2016-08-03 7 views
0

ソースコードthis gemをブラウズしていましたが、私に多くの混乱を招くcontent_tagの使用が見つかりました。Rails content_tagメソッド

def render(view) 
    view.content_tag(name, attributes[:content], attributes.except(:content)) 
end 

なぜcontent_tagが表示されているのかわかりません。私は一般的にヘルパーとしてHTMLタグを生成するためにそれを使用しますが、メソッドとして呼び出すことはありません。

答えて

2

は最も一般的には、content_tagは、ビューのコンテキストで呼び出された - ビューがcontent_tagに応答する方法を知っているのでそう、あなたはview.content_tagを呼び出す必要はありません(単にcontent_tagを呼び出すとself.content_tagを呼び出すのと同じです)。

表示されているrenderメソッドは、Tagから継承するクラスMetaTagに存在します。 Tagは普通のRubyオブジェクト(PORO)なので、content_tagへの返答方法はわかりません。

ご覧のとおり、renderメソッドは引数としてビューを受け取ります。そして、当然viewオブジェクトはcontent_tagへの応答方法を知っています。したがって、view.content_tagを呼び出すことは、MetaTagがコンテンツタグをレンダリングできる方法です。

これはPresenterパターンのインスタンスです(異なる人々は異なる用語を使用します)。 Ryan Batesはこのhereに良いRailsCastを持っています。

コメントの中で、RailsはviewActionView::Baseのインスタンスであることを「知っていません」。あなたは実際のビューインスタンスを渡す責任があります。私はコントローラに渡して、ビューとパラメータにアクセスできるようにする傾向があります。たぶん、このような何か:method_missing方法を含むことで

class FooController < ApplicationController 

    def foo_action 
    FooPresenter.present(self) 
    end 

end 

と...

class FooPresenter 
    class << self 

    def present(controller) 
     new(controller).present 
    end 

    end # class methods 

    #=================================================================== 
    # instance methods 
    #=================================================================== 

    def initialize(controller) 
     @controller = controller 
    end 

    def present 
     content_tag :div, data: {foo: params[:foo]}, class: 'bar' 
    end 

    private 

    def controller() @controller    end 
    def view()  controller.view_context end 
    def params()  controller.params   end 

    def method_missing(*args, &block) 
     view.send(*args, &block) 
    end 

end 

、私はもはやview.content_tagを呼び出す必要がありません。私はcontent_tagと呼ぶことができます。 FooPresenterはメソッドを見つけられないので、メソッドを見つけて実行するviewに呼び出しを送信します。

また、Ryanはこれをすべて説明する素晴らしい仕事をしています。

+0

あなたの説明とそのRailsCastを私に指摘してくれてありがとう。私はまだ1つのことを理解していません.Railsは 'view'がRailsビューの' ActionView :: Base'ビューインスタンスであることをどのように知っていますか? – davideghz

+0

あなたの更新された答えは素晴らしいですが、ActionView :: Baseインスタンスが実際にメソッドに渡される(宝石の)リンクされたソースコードの正確な行を教えてください。 – davideghz

+1

うわー!あなたは本当に私をこの仕事のために働かせています...(冗談)。したがって、参照されている宝石を詳しく調べると、ドキュメンテーションに**コントローラでメタタグを使用する**と**表示でメタタグを使用する**というメッセージが表示されます。これはPOROプレゼンターのパターンに従わないことを示しています。代わりに、MetaTagのメソッドは 'metaContents :: Base'と' ActionView :: Base'の両方に 'meta-tags/lib/meta_tags.rb'の36行目と37行目で呼ばれるインクルードメソッドを介して含まれています。これらの文脈では、 'view'は常に利用可能です。 – jvillian

1

content_tagはあまり詳しく説明しませんが、ActionView::Helpers::TagHelperクラスのメソッドです。私はこのクラスのオブジェクトが自動的にRailsビューに含まれるか、Railsビューのオブジェクトdelegateがこのオブジェクトに含まれると信じています。

方法はActionView::Helpers::TagHelperの一部であるcontent_tag方法、へのアクセスを有するように、この特定の宝石は、そのrenderメソッドのパラメータとしてActionView::Baseオブジェクトを取ります。これは、オブジェクト指向プログラミングの基本原理であるDependency Injectionのまともな例です。

関連する問題