ActiveRecord::Base.update 的 alias_method_chain 顺序变化 博客分类: Ruby ActiveRecordRailsRuby工作
程序员文章站
2024-03-16 10:06:34
...
alias_method_chain有非常强大的功能,使得我们对Rails的功能扩展变得很容易。考虑过当一个方法存在多个alias_method_chain时,without方法会变成什么样子呢?但一直没有做相关的调查。
在进行Rails2.2.2到2.3.8的升级过程中,终于遭遇了这个问题。
ActiveRecord::Base的update方法,有四个alias_method_chain:
由于我们的程序会在后台处理客户的信息,而不像改变updated_at,所以公有化了update_without_timestamps,显示的调用它。而在update_without_timestamps执行后,我们需要after_update来触发缓存的清空/更新。
Rails2.2.2里,method_chain实际工作顺序如下。update_without_timestamps执行后,正确的执行了callbacks来清空缓存,我们的程序工作正常。
update_with_timestamps # update_without_timestamps = update_with_callbacks
update_with_callbacks
update_with_dirty
update_with_lock
但是在2.3.8下,method_chain工作顺序变化了。执行update_without_timestamps的时候,直接跳过了update_with_callbacks,程序出错。
看来在享用alias_method_chain便利的同时,还要注意它的一些细节呀。
代码的修改其实很简单,只要利用ActiveRecord::Base.record_timestamps = false就好了。
在进行Rails2.2.2到2.3.8的升级过程中,终于遭遇了这个问题。
ActiveRecord::Base的update方法,有四个alias_method_chain:
base.alias_method_chain :update, :callbacks base.alias_method_chain :update, :timestamps base.alias_method_chain :update, :dirty base.alias_method_chain :update, :lock
由于我们的程序会在后台处理客户的信息,而不像改变updated_at,所以公有化了update_without_timestamps,显示的调用它。而在update_without_timestamps执行后,我们需要after_update来触发缓存的清空/更新。
Rails2.2.2里,method_chain实际工作顺序如下。update_without_timestamps执行后,正确的执行了callbacks来清空缓存,我们的程序工作正常。
引用
update_with_timestamps # update_without_timestamps = update_with_callbacks
update_with_callbacks
update_with_dirty
update_with_lock
但是在2.3.8下,method_chain工作顺序变化了。执行update_without_timestamps的时候,直接跳过了update_with_callbacks,程序出错。
引用
update_with_callbacks
update_with_timestamps # update_without_timestamps = update_with_dirty
update_with_dirty
update_with_lock
update_with_timestamps # update_without_timestamps = update_with_dirty
update_with_dirty
update_with_lock
看来在享用alias_method_chain便利的同时,还要注意它的一些细节呀。
代码的修改其实很简单,只要利用ActiveRecord::Base.record_timestamps = false就好了。