2013-09-03 3 views
19

Какой порядок выполняется перед фильтрами? В частности, в каком порядке применяются фильтры 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.

+0

У вас нет наследования '' '' A''' от некоторого контроллера, например * ActionController *? Если действие выполняется на экземпляре '' 'B''', сначала наследуются такие фильтры, как' '' set_user'''. –

+0

Извините. Починил это. –

+0

Как исправить заказ: http://stackoverflow.com/questions/5711797/how-can-i-specify-the-order-that-before-filters-are-executed –

ответ

19

Я предлагаю взглянуть на the source code и API Docs на фильтрах.

упорядочение по умолчанию должно быть

  1. :set_post
  2. :set_user

Я думаю, что если вы хотите, чтобы подтолкнуть :set_user к вершине стека можно изменить строку в A для

prepend_before_action :set_user 

Также стоит отметить, что это не единственный вопрос по теме; есть others here on SO.


Что касается конкретной ситуации, похоже, вам нужно изменить A как я уже говорил выше, для того, чтобы иметь @user присваиваться времени set_post в B прогонов.


По состоянию на 4.2.6 (вероятно, изменилась в более ранней версии), порядок теперь родитель, прежде чем ребенок:

  1. :set_user
  2. :set_post
+1

Спасибо. Это то, что мне нужно. –

+0

У вас есть заказ по умолчанию (выше) назад. До_фильтров производного класса (B) вызывается перед базовым классом (A) before_filters. Итак, это: 1.: set_user и 2.: set_post Также обратите внимание, что after_filters вызывается в обратном порядке, наиболее выводится первым. –

+6

Я просто попробовал это на Rails 4.2, и похоже, что это уже недействительно. Сначала выполняется обратный вызов родительского класса, а затем обратный вызов класса ребенка. Итак: 1) 'set_user', 2)' set_post' – head

0

Да, ваш код будет работать по назначению.

Предварительные_файлы в производном классе (B) вызывается перед before_filters в базовом классе (A). Таким образом, порядок методов, называемых являются:

  1. set_user()
  2. set_post()
  3. шоу()

Также отметим, after_filters вызываются в обратном порядке, наиболее получены первые ,

+2

Как вы сказали, before_filter в производном классе вызывается первым, так как B является производным классом, сначала будет вызываться set_post, а затем set_user. – DallaRosa

5

Принимаемый ответ больше недействителен с Rails 4.2.6. Вероятно, это было изменено ранее, но это версия, на которой я сейчас.

Родительские фильтры теперь вызывается перед детьми фильтров, поэтому порядок теперь будет:

  1. :set_user
  2. :set_post

И, если вы об этом думаете, что заказ действительно делает более смысл. Как уже говорилось, если вам нужно, чтобы ребенок вызывал фильтр перед родителем, вам нужно использовать prepend_before_action.

Смежные вопросы