在 Rails 中,before filters 的执行顺序是怎样的?

22

before_filter的执行顺序是什么?具体来说,在继承方面,before_action过滤器的顺序是什么?例如,这个是否有效:

class A < ActionController::Base
  before_action :set_user

  def set_user
    @user = something
  end
end

class B < A
  before_action :set_post

  def show
    render @post
  end

  def set_post
    @post = @user.posts.first
  end
end

B#show会生效吗?未来参考,过滤器的顺序规则是什么?我在Rails文档中找不到任何相关信息。


你的 A 类没有继承像 ActionController 这样的控制器吗?如果在 B 实例上执行操作,则会首先调用继承的过滤器,例如 set_user - David Unric
抱歉,已修复。 - Dylan Karr
如何修复顺序:https://dev59.com/IW025IYBdhLWcg3w76lq - Ciro Santilli OurBigBook.com
3个回答

25

我建议查看源代码和有关过滤器的API文档

默认的排序应该是

  1. :set_post
  2. :set_user

我认为,如果你想把:set_user推到堆栈的顶部,你可以更改A中的那行为:

prepend_before_action :set_user

另外值得指出的是,这不是该主题上唯一的问题;在SO上还有其他问题


至于你具体的情况,看起来你需要像我之前提到的那样更改A,以便在B中的set_post运行时已经分配给@user了。


从4.2.6版本开始(可能在早期版本中更改),现在的排序是父级在子级之前:

  1. :set_user
  2. :set_post

您的默认排序(如上所述)是反向的。派生类(B)上的before_filters在基类(A)之前被调用。因此,顺序应为:1. :set_user,2. :set_post另外请注意,after_filters按相反的顺序调用,最派生的先调用。 - Felix Livni
10
我刚在Rails 4.2上尝试了这个方法,看起来它已经不再有效了。现在父类的回调函数会先执行,然后是子类的回调函数。所以顺序是:1)set_user,2)set_post - head
如果您直接在答案上建议编辑,那将非常好。 - deefour

9
作为Rails 4.2.6版本的更新,原来被认可的答案已经不再适用了。可能更早就已经发生了变化,但这是我现在使用的版本。现在父过滤器会在子过滤器之前调用,所以顺序将会是: 1. :set_user 2. :set_post
如果你仔细想一想,这个顺序确实更合理。正如之前所说,如果你需要子过滤器在父过滤器之前调用,你需要使用prepend_before_action。

0

是的,您的代码将按预期工作。

派生类(B)上的 before_filters 在基类(A)上的 before_filters 之前被调用。因此,调用的方法顺序为:

  1. set_user()
  2. set_post()
  3. show()

另外请注意,after_filters 按相反的顺序调用,最派生的先调用。


2
正如你所说,派生类中的before_filter首先被调用,由于B是派生类,因此set_post将首先被调用,然后是set_user。 - DallaRosa

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