2013-03-18 4 views
7

私のアプリで各ページにレンダリングされたパーシャルをリストしたいと思っています。このページのレンダリングRuby on Rails:ページにレンダリングされる部分パスをどのようにリストしますか?

パーシャル:アプリ/タスク/ index.html.erbページが表示されたときに、例えば、私は、ユーザーに次のようなものを表示したい

タスク/ _list.html.erb
タスク/ _button.html.erb
タスク/ _navigation.html.erb

はRuby on Railsでそうする方法はありますか?

+0

私は確かに、サーバーログにはほぼ正確な行が印刷されていると考えています。私はミドルウェアスタックを見始めるだろう。 – bdares

+1

@bdares:ミドルウェアスタックにはない。これは計器コールです。 –

答えて

15

はい、そう完全にこれを実行する方法がありますがレール!

コメントで指摘されているように、テンプレートレンダリングの行はログに表示されます。しかし、彼らは最初にどのようにそこに着きますか?さて、これはlittle something in Active Support called LogSubscriberと関係があります。これに関するドキュメントはかなり徹底的です。

ActiveSupport :: LogSubscriberは、ActiveSupport :: Notificationsをロギングする目的でのみ使用するオブジェクトです。ログサブスクライバは、指定されたネームスペースに基づいて登録されたオブジェクトに通知をディスパッチします。

ログに「レンダリング...」の行を入れている事は、like this within Rails 3.2定義されてActionView::LogSubscriberです。コードを読んでください。それは素敵できれいです。これが何をしているか

はRailsの内のイベント、すなわちrender_templaterender_partialrender_collection方法のカップルに加入しています。これは、ActiveSupport::LogSubscriber.attach_toメソッドを呼び出して行います。このメソッドは、ログサブスクライバをいくつかのイベントに接続します。その方法は、また面白いです、そして、このように定義された:それは私たちの利益に非常に関連するですので、私はラインでこのコードを入れている

def attach_to(namespace, log_subscriber=new, notifier=ActiveSupport::Notifications) 
    log_subscribers << log_subscriber 
    @@flushable_loggers = nil 

    log_subscriber.public_methods(false).each do |event| 
    next if 'call' == event.to_s 

    notifier.subscribe("#{event}.#{namespace}", log_subscriber) 
    end 
end 

。これは、notifierオブジェクトでsubscribeを呼び出すことです。 notifierオブジェクトは、デフォルトではActiveSupport::Notificationsです。これは覚えておくことが重要です。 documentation for that class in Rails is in the API too

subscribeが呼び出されると、eventの名前を通過します。これは何ですか?まあ、それはクラス内のすべての単一のパブリックメソッドです。LogSubscriberサブクラスが定義されている場合、それはいくつかのパブリックメソッド、すなわちrender_template,render_partialおよびrender_collectionを定義します。これらは、このログサブスクライバに対してサブスクライブされるイベントです。私たちはビュー内のこれらのイベントをサブスクライブするために同じものを使用するつもりので


さて、それは私たちの利益に関連するのです。最初のステップでは、ActiveSupport::Notfications、すべて部分レンダリングイベントを購読したいと考えています。私たちはApplicationController内に新しいbefore_filterを作成することによってこれを行うことができます。

before_filter :log_partial_events 

def log_partial_events 
    @partial_events = [] 
    ActiveSupport::Notifications.subscribe("render_partial.action_view") do |event_name, start_at, end_at, id, payload| 
    @partial_events << payload[:identifier] 
end 

我々はサブスクライブしているイベントが正確ActionView::LogSubscriberがに加入しているイベントの一つであるaction_view名前空間内render_partialイベントです。部分的にレンダリングされると、このブロックが呼び出され、いくつかのデータが渡されるということが起こります。

event_name:イベントの名前。 start_at:イベントが開始された時間。 end_at:イベントが終了した時刻。 id:このイベントの一意の識別子。 ​​:このイベントに関するペイロード情報。

フックが呼び出されると、メソッドの先頭に定義されている配列に​​のidentifierキーが追加されます。あなたがこれを行うことができますこれらのリストにアクセスするためのビューで次に

、このようなデバッグ情報をたくさんのために

<%= debug @partial_events %> 
+2

これは素晴らしいです、Ryan!それは完璧に働いた。信じられないほど明確なチュートリアルと指示をありがとう! :) – sjsc

+0

恐ろしい答えライアン、ありがとう! –

+0

グッドチップ、ありがとう!提案:あなたの例におけるブロックのインデント、あるいはメソッド定義の終わりのステートメントは、何が起こっているのかをより明確にするかもしれません。 – alegscogs

4

Notification APIから次の例では、あなたを助ける必要があります。

ActiveSupport::Notifications.subscribe("render") do |*args| 
    events << ActiveSupport::Notifications::Event.new(*args) 
end 

をあなたの場合、あなたが'render_partial.action_view'通知をしたい(レンダリングされたパーシャルを追跡する)ため。あなたのコードは次のようになります。

class ApplicationController < ActionController::Base 
    before_filter :subscribe_to_render 

    private 
    def subscribe_to_render 
    @render_events = [] 
    ActiveSupport::Notifications.subscribe("render_partial.action_view") do |*args| 
     @render_events << ActiveSupport::Notifications::Event.new(*args) 
    end 
    end 
end 

をそして、あなたは、この情報を表示したいところはどこでも、あなたは、このヘルパーメソッドを使用できます

def display_render_events 
    raw(@render_events.map do |event| 
    event.payload[:identifier].gsub(/^.*app\/views\//, '') 
    end.join('<br/>')) 
end 
+1

この問題を解決するのに非常に似たアプローチがありました。偉大な心とすべてのもの:) –

+2

@RyanBigg:編集のおかげで:)違いは、あなたがそれがどこにあったのか分かっていた間に、私はそれを見つけるために実際に掘り下げなければならなかったということでした。 – PinnyM

+0

リンクありがとうございましたPinny!あなたとライアンは素晴らしいです:) – sjsc

2

を見ているあなたはまた、チェックすることをお勧めしますRailsPanelこれはChromeの拡張機能です。

関連する問題