require'active_support'classAuditdefbefore(caller)puts'Audit: before is called'enddefbefore_save(caller)puts'Audit: before_save is called'endendclassAccountincludeActiveSupport::Callbacks define_callbacks :save set_callback :save, :before,Audit.newdefsave run_callbacks :save doputs'save in main'endendendAccount.new.save
此时,我们可以使用 define_callbacks 的 scope 参数进行解决。也就是:
define_callbacks :save, scope: [:kind, :name]
Rails 里 Callback 相关的模块及继承关系
ActiveRecord::Callbacks
|
V
ActiveModel::Callbacks
|
V
ActiveSupport::Callbacks
ActiveModel::Validations::Callbacks
ActiveJob::Callbacks
ActionDispatch::Callbacks
AbstractController::Callbacks
|
V
ActiveSupport::Callbacks
Filters 顺序
一条"回调链"上可以有多个"回调",它们彼此之间不是独立的,有先后顺序。即:
Before,After,Around
但这些"回调"也有终结的时候。即:
End
定义、运行回调
define_callbacks 定义的时候会:
define_callbacks
|
V
set_callbacks name, CallbackChain.new(name, options) # 这里的 name 表示"回调链"的名字。
def set_callbacks(name, callbacks) # 这里的 callbacks 是"回调链"的实例对象。
send "_#{name}_callbacks=", callbacks
end
define_callbacks
|
V
def _run_#{name}_callbacks(&block)
_run_callbacks(_#{name}_callbacks, &block)
end
run_callbacks 运行的时候会:
run_callbacks
|
V
_run_#{kind}_callbacks # 这里的 kind 表示"某种类型的"回调链
|
V
_run_callbacks(_#{name}_callbacks, &block) # 这里的 name 表示"回调链"
|
V
runner = callbacks.compile # 这里的 callbacks 表示"回调链";
# compile 会创建 Callback 实例对象并做后续处理。
e = Filters::Environment.new(self, false, nil, block)
runner.call(e).value