何时在Rails应用程序中执行条件before_action方法?

时间:2017-08-30 15:09:41

标签: ruby-on-rails ruby

在以下代码中,为什么foo_enabled?要求EmployeeController.bar

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

2 个答案:

答案 0 :(得分:2)

我认为原因是一旦你开始在你的回调上使用条件,那么总是会检查回调以查看它们是否应该运行。

你会非常合理地认为skip_会从该操作的回调中完全删除该回调。相反,我认为,它增加了一个条件。 only:条件会添加unless: Proc.new { action_name == 'bar' }之类的支票。

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

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

答案 1 :(得分: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