Active Model Callbacks¶ ↑
提供一个接口,让任何类都可以拥有类似 Active Record 的回调。
与 Active Record 方法类似,只要其中一个方法抛出 :abort,回调链就会中止。
首先,在您创建的类中扩展 ActiveModel::Callbacks。
class MyModel extend ActiveModel::Callbacks end
然后定义您希望回调附加到的一系列方法。
define_model_callbacks :create, :update
这将为 :create 和 :update 方法提供所有三种标准回调(before、around 和 after)。要实现这一点,您需要将您想要回调的方法包装在一个块中,以便回调有机会触发。
def create run_callbacks :create do # Your create action methods here end end
然后,在您的类中,您可以像在 Active Record 模型中一样使用 before_create、after_create 和 around_create 方法。
before_create :action_before_create def action_before_create # Your code here end
定义 around 回调时,请记住 yield 给块,否则它将不会被执行。
around_create :log_status def log_status puts 'going to call the block...' yield puts 'block successfully called.' end
您可以选择只拥有特定的回调,方法是将一个哈希传递给 define_model_callbacks 方法。
define_model_callbacks :create, only: [:after, :before]
将在您的类中只创建 after_create 和 before_create 回调方法。
注意:多次定义同一个回调将覆盖以前的回调定义。
实例公共方法
define_model_callbacks(*callbacks) Link
define_model_callbacks 接受与 define_callbacks 相同的选项,以防您想覆盖默认值。除此之外,它还接受一个 :only 选项,您可以在其中选择是否需要所有类型(before、around 或 after)或只是一些。
define_model_callbacks :initialize, only: :after
注意,only: <type> 哈希将应用于在该方法调用中定义的所有回调。要解决此问题,您可以根据需要多次调用 define_model_callbacks 方法。
define_model_callbacks :create, only: :after define_model_callbacks :update, only: :before define_model_callbacks :destroy, only: :around
将只创建 after_create、before_update 和 around_destroy 方法。
您可以将一个类传递给 before_<type>、after_<type> 和 around_<type>,在这种情况下,回调将调用该类的 <action>_<type> 方法,并将正在调用回调的对象传递给它。
class MyModel extend ActiveModel::Callbacks define_model_callbacks :create before_create AnotherClass end class AnotherClass def self.before_create( obj ) # obj is the MyModel instance that the callback is being called on end end
注意:传递给 define_model_callbacks 的 method_name 不能以 !、? 或 = 结尾。
# File activemodel/lib/active_model/callbacks.rb, line 109 def define_model_callbacks(*callbacks) options = callbacks.extract_options! options = { skip_after_callbacks_if_terminated: true, scope: [:kind, :name], only: [:before, :around, :after] }.merge!(options) types = Array(options.delete(:only)) callbacks.each do |callback| define_callbacks(callback, options) types.each do |type| send("_define_#{type}_model_callback", self, callback) end end end