2013-03-18 49 views
7

我正在尋找列出爲我的應用程序中的每個頁面呈現的部分。例如,顯示在應用程序/任務/ index.html.erb頁面的時候,我想顯示類似下面的用戶:呈現此頁面Ruby on Rails:如何列出爲頁面呈現的部分路徑?

局部模板:

任務/ _list.html.erb
任務/ _button.html.erb
任務/ _navigation.html.erb

有沒有辦法在Ruby on Rails的這樣做呢?

+0

我確信有一種方法,考慮到幾乎那些確切的行打印在服務器日誌中。我開始看中間件堆棧... – bdares 2013-03-18 02:34:11

+1

@bdares:它不在中間件堆棧中。這是一個儀器調用。 – 2013-03-18 02:58:22

回答

15

是的,有這樣完全是一個方式來做到這一點Rails的!

正如bdares在他的評論中指出的,模板渲染的線條出現在日誌中。但他們如何才能到達那裏呢?那麼,這與little something in Active Support called LogSubscriber有關。這個文件是非常徹底的:

ActiveSupport :: LogSubscriber是一個對象設置爲使用ActiveSupport ::通知,其唯一目的是記錄它們。日誌訂閱者根據給定的名稱空間將通知分派給已註冊的對象。

將日誌中的「Rendered ...」行放入日誌的東西是ActionView::LogSubscriber,定義爲like this within Rails 3.2。花點時間閱讀代碼。它很好,很整齊。

這是什麼東西做的是訂閱內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對象上調用subscribenotifier對象默認爲ActiveSupport::Notifications,這一點很重要。 documentation for that class in Rails is in the API too

當調用subscribe時,它會通過event的名稱。這是什麼?嗯,這是班裏每一個公共的方法。當定義子類別LogSubscriber時,它定義了幾個公共方法:render_template,render_partialrender_collection。這些是將爲這個日誌訂閱者訂閱的事件。現在


,因爲我們將使用同樣的事情訂閱視圖內這些事件是有關我們的利益。第一步是讓ActiveSupport::Notfications我們要訂閱全部部分渲染事件。我們可以通過創建內ApplicationControllerbefore_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 

我們訂閱的事件是action_view命名空間,這正是ActionView::LogSubscriber訂閱了該事件的一個內render_partial事件。局部渲染時會發生什麼情況是該塊將被調用並傳入一些數據。

event_name:事件的名稱。 start_at:事件開始的時間。 end_at:事件結束的時間。 id:此事件的唯一標識符。 ​​:關於此事件的一些有效載荷信息。

當掛鉤被調用時,它會將identifier鍵從​​添加到方法頂部定義的數組中。

然後在視圖,來訪問這些列表,你可以這樣做:

<%= debug @partial_events %> 
+2

這真是太棒了,瑞恩!它工作完美。感謝您提供令人難以置信的明確教程和說明! :) – sjsc 2013-03-18 03:48:29

+0

真棒回答瑞安,謝謝! – 2013-03-18 14:04:58

+0

偉大的提示,謝謝!建議:您的示例中某個塊的縮進或者方法定義的關閉結束語句可能會使得它更清晰。 – alegscogs 2013-11-07 18:20:07

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

有趣的是,我們有一個非常類似的方法來解決這個問題。偉大的思想和所有:) – 2013-03-18 03:34:21

+2

@RyanBigg:感謝編輯:)不同的是,我不得不實際深入找到它,而你知道它一直在哪裏。 – PinnyM 2013-03-18 03:45:44

+0

感謝您的鏈接Pinny!你和Ryan都很棒:) – sjsc 2013-03-18 03:51:10

2

您可能還需要檢查RailsPanel這是一款Chrome擴展程序。