我该如何指定 before_filters 执行的顺序?

70

Rails是否保证在以下两种用法中before filter执行的顺序?

before_filter [:fn1, :fn2]
或者
before_filter :fn1
before_filter :fn2

我会非常感激任何帮助。

4个回答

87
如果您参考了http://api.rubyonrails.org/v2.3.8/classes/ActionController/Filters/ClassMethods.html,那么这里有一个名为“Filter chain ordering”的子标题,以下是来自该子标题的示例代码:
class ShoppingController < ActionController::Base
    before_filter :verify_open_shop

class CheckoutController < ShoppingController
    prepend_before_filter :ensure_items_in_cart, :ensure_items_in_stock

根据解释:

CheckoutController的筛选器链现在为:ensure_items_in_cart:ensure_items_in_stock:verify_open_shop.

因此,您可以明确地指定筛选器链的顺序。


正是我所需要的。@Johnny 你真是我的救命恩人。非常感谢你。 - Surya
@Sector和JohnnyWoo:你们提供的http://rails.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html链接已经失效了。 - Kevin
1
在 Rails 3.2.14 中,我得到的过滤器链是以下内容::ensure_items_in_stock, :ensure_items_in_cart, :verify_open_shop。 - Raf
更新链接:http://api.rubyonrails.org/v2.3.8/classes/ActionController/Filters/ClassMethods.html - Lucy Bain
1
一个输出和调试确切过滤器链的命令会很有帮助。 - Epigene

25

3
如果两者都失败并尝试重定向,那不会造成问题吗? - Groxx
你可以在fn3中使用if,以检查fn1和fn2的返回结果。 - Sector
如果 fn1 失败(即返回 false)并且不需要执行 fn2,则必须添加更多的逻辑。类似这样:fn1 ? fn2 : false - Eric H.

3
据我所知,您需要按照顺序放置要执行的第一个函数及其后续函数。
因此,应该像这样:

例如:

before_filter :fn1, :fn2

def fn1
  puts 'foo'
end

def fn2
  puts 'bar'
end

将会先执行 fn1,然后执行 fn2

希望这有所帮助。


我正在使用Rails 4,即使我的顺序是:fn1, :fn2,但是:fn2先被调用了。 - r3b00t

2
< p > CheckoutController 的过滤器链不遵循这个顺序。< /p >
:ensure_items_in_cart, :ensure_items_in_stock, :verify_open_shop

相反,应该是
:ensure_items_in_stock, :ensure_items_in_cart, :verify_open_shop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接