我想在控制器中定义一个before_filter,但总是让它最后执行。
我知道append_before_filter,但是我想在一个模块中指定这个过滤器,其他类也可以在以后添加其他的before_filters。
有没有办法做到这一点?
答案 0 :(得分:3)
这是一个简单的模块,允许在完整的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
请注意,您应该小心这样做,因为控制器本身可能会根据声明顺序对过滤器排序做出假设。
答案 1 :(得分:2)
我不知道实现这一目标的优雅方式。但是,使用一些横向思维......你可以确保你的所有控制器都使用prepend_before_filter
。这样,如果您的模块使用before_filter
,您将知道它将始终是最后一个过滤器,因为控制器将始终将其过滤器添加到过滤器链的开头。
答案 2 :(得分:2)
您可以覆盖模块中的before_filter
,或让self.included
回调挂钩声明alias_method_chain :before_filter, :final_filter
。对于您希望能够移植到多个版本的Rails的代码,或者您将发布要在其他上下文中使用的代码,建议不要这样做。
答案 3 :(得分:1)
根据rails API,默认的“before_filter”是“append_before_filter”的别名,它将过滤器附加到filter_chain列表的末尾。我会说有一个合理的假设,如果你在控制器中正确地命令过滤器,它们将被按顺序执行。如前面的答案所示,还有一个“prepend_before_filter”可确保您添加的过滤器位于filter_chain的前面。