ActiveRecord 回调如何在 Rails 中实际工作



我已经浏览了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的行。

然而,我无法弄清楚的是两个关键要素。

  1. ActiveRecord 如何/在哪里实际触发回调,以及该方法在哪里,该方法生成到传递给要执行的回调的方法的符号。

  2. 活动记录如何知道回调甚至退出? 也就是说,它是如何从类声明变成由 ActiveRecord 执行的? 它是加载到某种寄存器中还是每次加载都检查什么;等?

ActiveRecord 和 ActiveModel 使用 ActiveSupport::Callbacks 来完成它们的肮脏工作。

如果你看一下它的ClassMethods模块,你会发现define_callbacks定义(通过module_eval(_run_update_callbacks和朋友。_run_*_callbacks方法只是从主模块调用run_callbacks

所以要回答你的问题:

  1. 我相信ActiveRecord实际上触发了您发布的代码中的回调。看起来ActiveRecord::Transactions有几个它正在运行的(与事务相关的,很有趣(。

  2. 不用深入挖掘,看起来run_callbacks方法只是保留所有回调的列表,然后检查并弄清楚是什么以及该做什么。

可能没有你希望的那么深入的答案,但希望这至少能让你朝着正确的方向前进,自己挖掘和调查。

最新更新