【发布时间】:2011-06-25 19:31:13
【问题描述】:
我有一个场景,当我在布局文件中时,我想拥有将要呈现的视图的名称。我可以找到解决方案来查找哪个布局将从视图中包装当前视图,但不能反过来。如何找到正在渲染的视图?
【问题讨论】:
标签: ruby-on-rails templates layout
我有一个场景,当我在布局文件中时,我想拥有将要呈现的视图的名称。我可以找到解决方案来查找哪个布局将从视图中包装当前视图,但不能反过来。如何找到正在渲染的视图?
【问题讨论】:
标签: ruby-on-rails templates layout
我喜欢以下方法,因为您可以在很多情况下大大减少代码大小。将此包含在您的 application_controller.rb 中:
before_filter :instantiate_controller_and_action_names
caches_action :instantiate_controller_and_action_names
def instantiate_controller_and_action_names
@current_action = action_name
@current_controller = controller_name
end
然后,如果您的视图对应于一个操作,您只需:
dosomething if @current_action == 'new'
【讨论】:
在 Rails 3.0.3 中,我可以使用 controller_name 和 action_name 查看控制器和操作的名称。但这些都没有公开记录(至少是动作名称),所以我不会长期依赖它。
猴子补丁模板渲染可能会更好。在初始化器中:
module ActionView::Rendering
alias_method :_render_template_original, :_render_template
def _render_template(template, layout = nil, options = {})
@last_template = template
_render_template_original(template, layout, options)
end
end
然后在你的布局中使用@last_template。
【讨论】:
ActionView::Rendering 在 Rails 3.1 中不再存在。
以下解决方案适用于 Rails 3.1。将此代码放在初始化程序中。 (rails 3.0.3 的答案在 Rails 3.1 中不再起作用)
这会为每个控制器启用一个@active_template 变量。这是一个 ActionViewTemplate 类的实例。
方法 active_template_virtual_path 方法以“控制器/动作”形式将模板作为名称返回
class ActionController::Base
attr_accessor :active_template
def active_template_virtual_path
self.active_template.virtual_path if self.active_template
end
end
class ActionView::TemplateRenderer
alias_method :_render_template_original, :render_template
def render_template(template, layout_name = nil, locals = {})
@view.controller.active_template = template if @view.controller
result = _render_template_original( template, layout_name, locals)
@view.controller.active_template = nil if @view.controller
return result
end
end
【讨论】:
@view.assign(:active_template => template) 位于render_template 中,但您可以删除一堆额外的代码并以@active_template 的身份访问视图中的模板。
@view.controller.active_template = template if @view.controller && @view.controller.active_template.nil?