2017-08-30 74 views
1

在下面的代码中,为什么foo_enabled?要求EmployeeController.bar何时在Rails应用程序中执行条件before_action方法?

class ApplicationController < ActionControlelr::Base 
    before_action :foo, if: :foo_enabled? 
    def foo 
     puts 'foo called' 
    end 

    def foo_enabled? 
     puts 'sleep for 100s !' 
     true 
    end 
end 

class EmployeeController < ApplicationController 
    skip_before_action :foo, only: [:bar] 

    def bar 
     puts 'inside bar' 
    end 
end 

回答

1

foo_enabled?是,如果foo应在所有所谓的条件。 然后确定foo应该被调用,但EmployeeController跳过它而不是bar

如果foo_enabled?返回false那么将没有foo行动执行,因此没有什么可以“跳过”。

由于before_action基于if有条件,因此必须先评估if以确定操作是否应触发。

确定后,skip_before_action评估是否应该跳过。简化工作流程说明:

#ApplicationController 
if foo_enabled? 
    #EmployeeController 
    if skip_action == :foo && !skip_action[:only].includes?(current_action) 
    foo 
    end 
end 
1

我想原因是,一旦你开始使用你的回调条件,则回调总是检查,看他们是否应该运行。

你会认为,相当合理地,skip_会从该行为的回调中完全删除该回调。相反,我认为,它增加了一个条件。 only:条件增加了一个类似unless: Proc.new { action_name == 'bar' }的检查。

根据条件得到检查的顺序,很可能您的foo_enabled?条件在only:条件之前被检查,这就是为什么你看到你的方法被调用的原因。代码遍历回调以检查它们是否应该运行,并且在EmployeeController中添加之前检查ApplicationController的条件。

相关代码位于activesupport gemlib/active_support/callbacks.rbactionpack gemlib/abstract_controller/callbacks.rb中。这对我来说有点困难,但我认为我所描述的是它的本质。

相关问题