我已经浏览了ActiveRecord回调的源代码;我可以看到回调的ActiveRecord关注点,如下所示:
module Callbacks
extend ActiveSupport::Concern
CALLBACKS = [
:after_initialize, :after_find, :after_touch, :before_validation, :after_validation,
:before_save, :around_save, :after_save, :before_create, :around_create,
:after_create, :before_update, :around_update, :after_update,
:before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
]
def destroy #:nodoc:
@_destroy_callback_already_called ||= false
return if @_destroy_callback_already_called
@_destroy_callback_already_called = true
_run_destroy_callbacks { super }
rescue RecordNotDestroyed => e
@_association_destroy_exception = e
false
ensure
@_destroy_callback_already_called = false
end
def touch(*) #:nodoc:
_run_touch_callbacks { super }
end
private
def create_or_update(*)
_run_save_callbacks { super }
end
def _create_record
_run_create_callbacks { super }
end
def _update_record(*)
_run_update_callbacks { super }
end
end
end
现在我可以通过符号数组的常量看到可用的回调。
进一步的调查表明,来自回调的create_or_update(*)
方法涉及从 persistance.rb 文件(为模型执行 CRUD 操作(调用 - 并使用类似@_trigger_update_callback = result
的行。
然而,我无法弄清楚的是两个关键要素。
ActiveRecord 如何/在哪里实际触发回调,以及该方法在哪里,该方法生成到传递给要执行的回调的方法的符号。
活动记录如何知道回调甚至退出? 也就是说,它是如何从类声明变成由 ActiveRecord 执行的? 它是加载到某种寄存器中还是每次加载都检查什么;等?
ActiveRecord 和 ActiveModel 使用 ActiveSupport::Callbacks 来完成它们的肮脏工作。
如果你看一下它的ClassMethods模块,你会发现define_callbacks
定义(通过module_eval
(_run_update_callbacks
和朋友。_run_*_callbacks
方法只是从主模块调用run_callbacks
。
所以要回答你的问题:
-
我相信ActiveRecord实际上触发了您发布的代码中的回调。看起来ActiveRecord::Transactions有几个它正在运行的(与事务相关的,很有趣(。
-
不用深入挖掘,看起来
run_callbacks
方法只是保留所有回调的列表,然后检查并弄清楚是什么以及该做什么。
可能没有你希望的那么深入的答案,但希望这至少能让你朝着正确的方向前进,自己挖掘和调查。