什么时候是around_create回调代码执行,在什么情况下我们应该使用它?
也有这个问题,现在已经找到了答案:around_create
允许你在一种方法中基本上同时做before_create
和after_create
。你必须使用yield
来执行之间的保存。
class MyModel < ActiveRecord::Base
around_create :my_callback_method
private
def my_call_back_method
# do some "before_create" stuff here
yield # this makes the save happen
# do some "after_create" stuff here
end
end
刚刚找到一个用例:
想象一下多态观察者的情况,观察者在某些情况下需要在保存之前执行操作,在其他情况下需要执行操作。
使用around过滤器,您可以捕获块中的保存操作并在需要时运行它。
class SomeClass < ActiveRecord::Base
end
class SomeClassObserver < ActiveRecord::Observer
def around_create(instance, &block)
Watcher.perform_action(instance, &block)
end
end
# polymorphic watcher
class Watcher
def perform_action(some_class, &block)
if condition?
Watcher::First.perform_action(some_class, &block)
else
Watcher::Second.perform_action(some_class, &block)
end
end
end
class Watcher::First
def perform_action(some_class, &block)
# update attributes
some_class.field = "new value"
# save
block.call
end
end
class Watcher::Second
def perform_action(some_class, &block)
# save
block.call
# Do some stuff with id
Mailer.delay.email( some_class.id )
end
end
“around”过滤器的典型用例是测量性能,或记录或执行其他状态监视或修改。
除了Tom Harrison Jr's answer关于记录和监控之外,我发现关键的区别在于控制操作是否完全运行。否则,你可以实现自己的before_*
和after_*
回调来做同样的事情。
以around_update
为例。假设您有一个不希望更新运行的情况。例如,我正在构建一个gem,它将草稿保存在另一个drafts
表中,但不保存对“master”表的某些更新。
around_update :save_update_for_draft
private
def save_update_for_draft
yield if update_base_record?
end
这里引用的update_base_record?
方法的细节并不重要。您可以看到,如果该方法未评估为true
,则更新操作将无法运行。
保存带有around_create
标志的模型时调用new?
。它可以用来添加数据来添加/更改模型的值,调用其他方法等等...我不能知道这个回调的特定用例,但它完成了一组“之前,之后,周围”创建操作的回调。对于查找,更新,保存和删除事件,存在类似的“之前,之后,周围”回调集。
关于我发现的回调的简单而整洁的解释如下
围绕操作以及before_ *和after_ *操作内部调用around_ *回调。例如:
class User
def before_save
puts 'before save'
end
def after_save
puts 'after_save'
end
def around_save
puts 'in around save'
yield # User saved
puts 'out around save'
end
end
User.save
before save
in around save
out around save
after_save
=> true
最初发布here