我想在控制器中定义一个before_filter,但总是要最后执行它。有没有办法强制before_filter总是最后执行?
我知道append_before_filter,但我想在模块中指定此过滤器,其他类可能稍后会添加其他before_filters。
有没有办法做到这一点?
我想在控制器中定义一个before_filter,但总是要最后执行它。有没有办法强制before_filter总是最后执行?
我知道append_before_filter,但我想在模块中指定此过滤器,其他类可能稍后会添加其他before_filters。
有没有办法做到这一点?
我不知道一个优雅的方式来实现这一点。但是,使用一些横向思维......你可以确保你的所有控制器都使用prepend_before_filter
。这样,如果您的模块使用before_filter
,您将知道它始终是最后一个过滤器,因为控制器将始终将其过滤器添加到过滤器链的开头。
根据rails API,默认的“before_filter”是“append_before_filter”的别名,它将过滤器附加到filter_chain列表的末尾。我会说有一个合理的假设,如果您在控制器中正确地命令您的过滤器,他们将被执行,以便他们列出。正如前面的答案所示,还有一个“prepend_before_filter”,可确保您添加的过滤器位于filter_chain的前端。
您可以在模块中覆盖before_filter
或使self.included
回调挂钩声明alias_method_chain :before_filter, :final_filter
。对于您希望能够跨越多个版本的Rails进行移植的代码,或者您将发布要在其他上下文中使用的代码的情况,建议不要这样做。
下面是一个简单的模块,它允许在整套before_filters之后执行任意代码。通过一些小小的工作,你可以清理它,这样在这里执行一个特殊的after_before_filters
队列(用适当的暂停行为,等等)。
module OneLastFilterModule
def self.included(base)
base.class_eval do
def perform_action_without_filters_with_one_last_filter
#
# do "final" before_filter work here
#
perform_action_without_filters_without_one_last_filter
end
alias_method_chain :perform_action_without_filters, :one_last_filter
end
end
end
请注意,您应该小心这样做,因为控制器本身可能会根据声明顺序对过滤器顺序进行假设。