假设我在基本控制器中有一些逻辑将信息传递给视图以构建类似于痕迹的东西:
class ContextAwareController < ApplicationController
after_filter :build_breadcrumb
def build_breadcumb
#...
end
end
我希望这个build_breadcrumb方法在主控制器逻辑之后运行,但之前呈现视图。
上面的代码运行得太晚,但是before_filter太早了。
在没有在子控制器中的每个操作结束时显式调用build_breadcumb的情况下,是否可以建议一种方法来实现此目的?
由于
答案 0 :(得分:52)
我遇到了同样的问题并解决了这个问题:
class ApplicationController < ActionController::Base
def render *args
add_breadcrumbs
super
end
end
答案 1 :(得分:2)
我相信渲染在调用渲染时开始,并且没有默认的方法来推迟渲染。这是你可以做的一件事:
过滤器以声明的相同顺序应用。因此,制作第二个使用存储在类变量中的数组args调用render的后过滤器。然后在通常调用渲染的任何地方设置变量。
答案 2 :(得分:2)
还有一些宝石可以实现这一目标。其中一个是rails3_before_render。 它与过滤器类似,例如:
class PostsController < ApplicationController
before_render :ping, :except => [:destroy]
def index; end
def new; end
def show; end
def destroy; end
private
def ping
Rails.logger.info "Ping-Pong actions"
end
end
(从gem文档复制的代码剪辑)
答案 3 :(得分:2)
如果我们覆盖render
,我们根本就没有真正使用过滤器链,因此确定我们使用{{1}时所采取的操作可能更为简单}}
@_action_name
答案 4 :(得分:0)
您可以像这样使用alias_method_chain
alias_method_chain :render, :before_render_action
这将创建2个方法:render_with_before_render_action
和:render_without_before_render_action
。如果调用渲染,则将调用:render_with_before_render_action
。您可以覆盖此方法
def render_with_before_render_action(*options, &block)
<your code>
render_without_before_render_action(*options, &block)
end
如果您不想执行代码,并且想要使用默认渲染,则应直接调用:render_without_before_render_action
答案 5 :(得分:-1)
你可以这样伪造一个before_render:
class StuffController < ApplicationController
before_filter :my_filter, only: [:index, :show]
def my_filter
@my_filter = true
end
def _my_filter
# Do the actual stuff here
end
def render(*args)
_my_filter if @my_filter
super
end
end
感谢@ joshua-muheim关于使用render