如何在Rails中组织复杂的回调?

我有一个Rails应用程序,它使用了很多回调..所以我有很多函数被调用:after_create和:after_commit在多个模型中。

我想知道我现在这样做的方式是最好的。

基本上我有以下场景:

Class Parent  "Richard The Lion Heart") self.processed = true self.save! end end def last_function if self.processed? if !self.processing? self.process self.save! self.processing = true self.save! end end end end 

所以你可以看到整个事情依赖于一些奇怪的双布尔检查,因为否则每次更新模型时都会调用second_function,并且它可以由函数本身更新,因此函数会被重复调用。

总的来说,它引出了我必须为每个回调引入一个新的布尔检查的情况。 它有效,但我不认为它优雅。 我错过了什么?

你应该能够重写那些代码 – 像这样的东西? 当然,您的真实代码可能还有一些额外的复杂性 – 另外: 此代码未经测试

 Class Parent < ActiveRecord::Base has_many :children # only called when a new record is created after_create :first_function # only called for updates, not new records, should still be inside the current transaction after_update :last_function private def first_function self.children.create(:name => "Richard The Lion Heart") # don't call save in here, already in a transaction end def last_function self.process # don't call save in here, already in a transaction end def process # doing stuff .... self.children[0].update_attribute(:name, "Beowulf") end end 

http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

这总共有十二个回调,它为您提供了巨大的力量来为Active Record生命周期中的每个州做出反应和准备。 为现有记录调用Base#save的顺序类似,只是每个_create回调都被相应的_update回调替换。

用法

 p = Parent.new(:foo => "bar") p.save p.children[0].name # => "Richard The Lion Heart" p.update_attributes(:baz => "fud") p.children[0].name # => Beowulf 

来自rails控制台的ActiveRecord回调(使用awesome_print ap)

 > ap ActiveRecord::Callbacks::CALLBACKS [ [ 0] :after_initialize, [ 1] :after_find, [ 2] :after_touch, [ 3] :before_validation, [ 4] :after_validation, [ 5] :before_save, [ 6] :around_save, [ 7] :after_save, [ 8] :before_create, [ 9] :around_create, [10] :after_create, [11] :before_update, [12] :around_update, [13] :after_update, [14] :before_destroy, [15] :around_destroy, [16] :after_destroy, [17] :after_commit, [18] :after_rollback ]