可能重复:
What is the order of ActiveRecord callbacks and validations?
我来自Java的背景。我认为在Rails中非常怪异的一件事是你可以在类的下面设置回调函数,例如before_filter
。
class SomeController < ActionController::Base
before_filter Proc.new {.....}
end
我真的不明白它是如何运作的。我找到了解释before_filter
的{{3}}。我理解逻辑的流程,它只是一种方法。但我仍然不明白何时执行before_filter
来建立回调链。
答案 0 :(得分:12)
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
执行类似(但更复杂)的操作,并确保在您使用普通控制器方法之前调用您使用它定义的所有回调。
我希望这能为你解决一些问题。
答案 1 :(得分:1)
加载控制器文件时(即服务器启动时),before_filter
方法本身会运行。这意味着一旦定义了类就建立了回调链。
对于它设置的回调,控制器有一个process
方法,它采用一个动作的名称(比如“index”),并在process_action
中调用相应的动作方法。回调模块使用runs the callback。