8

アプリの各ページでレンダリングされたパーシャルを一覧表示したいと考えています。たとえば、app/tasks/index.html.erb ページが表示されている場合、次のような内容をユーザーに表示したいと思います。

このページ用にレンダリングされたパーシャル:

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

Ruby on Railsでこれを行う方法はありますか?

4

5 に答える 5

14

はい、Rails でこれを行う完全な方法があります。

bdares がコメントで指摘したように、テンプレート レンダリングの行がログに表示されます。しかし、そもそもどうやってそこにたどり着くのでしょうか? それは、Active Support の と呼ばれるちょっとしたものとLogSubscriber関係があります。これに関するドキュメントはかなり完全です:

ActiveSupport::LogSubscriber は、ActiveSupport::Notification をログに記録することのみを目的として消費するように設定されたオブジェクトです。ログ サブスクライバーは、指定された名前空間に基づいて登録済みオブジェクトに通知をディスパッチします。

ログに「Rendered ...」行を入れているのは、Rails 3.2 内でこのようにActionView::LogSubscriber定義されていることです。コードを読んでみてください。それは素晴らしく、きれいです。

render_templateこれが行っているのは、Rails 内のいくつかのイベント、つまりrender_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

このコードは私たちの関心に非常に関連しているため、このコードを記載しました。subscribeこれが行っているのは、notifierオブジェクトの呼び出しです。notifierオブジェクトはデフォルトで です。ActiveSupport::Notificationsこれは覚えておくことが重要です。Rails のそのクラスのドキュメントも API にあります。

subscribe呼び出されると、 の名前を通過しeventます。これは何ですか?まあ、それはクラス内のすべてのパブリック メソッドです。LogSubscriberサブクラスが定義されると、いくつかのパブリック メソッドが定義されます: render_templaterender_partialおよびrender_collection。これらは、このログ サブスクライバーに対してサブスクライブされるイベントです。


同じものを使用してビュー内のこれらのイベントをサブスクライブするため、これは私たちの興味に関連しています。最初のステップは、すべての部分レンダリング イベントActiveSupport::Notficationsをサブスクライブできるようにすることです。内に新しいを作成することでこれを行うことができます:before_filterApplicationController

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

サブスクライブしているイベントは、名前空間render_partial内のイベントであり、サブスクライブしているイベントの 1 つです。パーシャルがレンダリングされると、このブロックが呼び出されてデータが渡されます。action_viewActionView::LogSubscriber

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

フックが呼び出されると、メソッドの先頭で定義された配列にidentifierキーが追加されます。payload

次に、ビューでこれらのリストにアクセスするには、次のようにします。

<%= debug @partial_events %>
于 2013-03-18T03:33:15.793 に答える
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
于 2013-03-18T03:28:00.853 に答える
2

このような多くのデバッグ情報については、rails-footnotesをご覧ください。

于 2013-03-18T04:24:54.613 に答える
2

Chrome拡張機能であるRailsPanelを確認することもできます。

于 2013-03-18T14:21:18.353 に答える