Ruby on Rails:如何列出为页面呈现的部分路径?

问题描述 投票:7回答:5

我想列出我的应用程序中每个页面呈现的部分内容。例如,当显示app / tasks / index.html.erb页面时,我想向用户显示以下内容:

为此页面呈现的部分:

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

有没有办法在Ruby on Rails中这样做?

ruby-on-rails ruby ruby-on-rails-3
5个回答
14
投票

是的,在Rails中有这么完美的方法!

正如bdares在他的评论中指出的那样,模板渲染的线条出现在日志中。但是,他们如何在第一时间到达那里?嗯,这与little something in Active Support called LogSubscriber有关。这方面的文档非常详尽:

ActiveSupport :: LogSubscriber是一个设置为使用ActiveSupport :: Notifications的对象,其唯一目的是记录它们。日志订阅者基于其给定的命名空间向已注册的对象分派通知。

在日志中放置“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

我把这些代码排成一行,因为它与我们的兴趣非常相关。这样做是在subscribe对象上调用notifiernotifier对象默认为ActiveSupport::Notifications,这一点很重要。 documentation for that class in Rails is in the API too

subscribe被调用时,它会通过event的名字。这是什么?嗯,这是课堂上的每一个公共方法。当定义LogSubscriber子类时,它定义了几个公共方法:render_templaterender_partialrender_collection。这些是将为此日志订阅者订阅的事件。


现在,这与我们的兴趣相关,因为我们将使用相同的东西在视图中订阅这些事件。第一步是让ActiveSupport::Notfications我们想要订阅所有部分渲染事件。我们可以通过在before_filter中创建一个新的ApplicationController来做到这一点:

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命名空间中的action_view事件,这正是ActionView::LogSubscriber订阅的事件之一。渲染部分时会发生什么,这个块将被调用并传入一些数据。

event_name:活动的名称。 start_at:活动开始的时间。 end_at:活动结束的时间。 id:此活动的唯一标识符。 payload:有关此事件的一些有效负载信息。

当钩子被调用时,它会将identifier中的payload键添加到方法顶部定义的数组中。

然后在视图中,要访问这些列表,您可以执行以下操作:

<%= debug @partial_events %>

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

2
投票

有关这方面的大量调试信息,请查看rails-footnotes


2
投票

您可能还想查看RailsPanel这是一个Chrome扩展程序。


1
投票

这是一个旧帖子,但万一有人发现这个有用的一个非常简单的方法来列出所有视图和部分用于你点击通过你的网站是重新启动你的服务器只有grep为“渲染”,例如

rails s | grep "Rendered"
© www.soinside.com 2019 - 2024. All rights reserved.