我来自Java背景。我认为 Rails 中很奇怪的一件事是,您可以在类下设置回调函数,例如属性,例如before_filter
.
class SomeController < ActionController::Base
before_filter Proc.new {.....}
end
我真的不明白它是如何工作的。我发现这篇文章解释了before_filter
。我了解逻辑流程,这只是一种方法。但是我仍然不明白什么时候会before_filter
执行设置回调链。
我来自Java背景。我认为 Rails 中很奇怪的一件事是,您可以在类下设置回调函数,例如属性,例如before_filter
.
class SomeController < ActionController::Base
before_filter Proc.new {.....}
end
我真的不明白它是如何工作的。我发现这篇文章解释了before_filter
。我了解逻辑流程,这只是一种方法。但是我仍然不明白什么时候会before_filter
执行设置回调链。
before_filter
不是 Ruby 功能,它是Ruby on Rails(Web 框架)提供的类方法,您可以在控制器中使用它来执行一段代码,然后再在控制器中执行任何操作。
那么,Ruby on Rails 是如何做到这一点的呢?
当您在 Ruby 中定义一个类时,您实际上是在执行代码,请在 irb 中尝试:
class Hello
puts "defining hello..."
def greet
puts "Hello there"
end
end
当您定义类时,您会看到“定义你好...”被打印在终端中。你没有实例化任何对象,你只是定义了一个类,但是你可以在定义一个类的过程中执行任何代码。
你知道你可以定义“类方法”和“实例方法”,有趣的是你可以在定义类的同时调用你的类方法:
class MyClass
def self.add_component(component)
# Here @@components is a class variable
@@components ||= [] # set the variable to an empty array if not already set.
@@components << component # add the component to the array
end
add_component(:mouse)
add_component(:keyboard)
add_component(:screen)
def components
@@components # The @@ gets you the class variable
end
end
MyClass.new.components
=> [:mouse, :keyboard, :screen]
def self.add_component
定义了一个类方法,您可以在定义类的同时调用该方法。在此示例add_component
中,将键盘添加到类变量中的列表中,并且def components
实例方法(在此类的实例上调用)访问此类变量。类方法可以在父类中定义,并且它的工作方式相同。这个例子可能有点奇怪。
让我们再举一个例子。
class RubyOnSlugsController
def self.before_filter(callback)
@@callbacks ||= []
@@callbacks << callback
end
def execute_callbacks
@@callbacks.each { |callback| callback.call() }
return "callbacks executed"
end
end
class MyController < RubyOnSlugsController
before_filter Proc.new { puts "I'm a before filter!" }
before_filter Proc.new { puts "2 + 2 is #{2 + 2}" }
end
controller = MyController.new
controller.execute_callbacks
将输出:
I'm a before filter!
2 + 2 is 4
=> "callbacks executed"
Ruby on Rails 做了类似的事情(但更复杂)before_filter
,它确保你用它定义的所有回调在你的普通控制器方法之前被调用。
我希望这可以为您解决一些问题。
before_filter
当您的控制器文件被加载(即当您的服务器启动时)时,该方法本身就会运行。这意味着一旦定义了类,就会设置回调链。
至于它设置的回调,控制器有一个process
方法,该方法采用动作的名称(例如,“索引”),并在process_action
. 回调模块使用运行回调的实现覆盖此方法。