How to organize complex callbacks in Rails?

I have a Rails application that often uses callbacks .. so I have quite a few functions called: after_create and: after_commit in several models.

I wonder if the best way I'm doing now is the best.

I basically have the following scenario:

Class Parent < ActiveRecord::Base has_many :children after_create :first_function after_commit :last_function def first_function if !self.processed? self.children.create(:name => "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 

So, you can see that it all depends on some strange double logical checks, because otherwise the second_function function is called every time the model is updated, and it can be updated by the function itself, and therefore the function gets the called repeat.

In general, this leads me to the case where I have to introduce a new Boolean check for each callback to hide. It works, but I do not consider it elegant. What am I missing?

+6
source share
1 answer

You should be able to rewrite this code - something like this? Of course, your real code probably has some additional complexity - ALSO: this code has not been verified.

 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

A total of twelve callbacks that give you tremendous power to respond and prepare for each state in the Active Record life cycle. The sequence for calling Base # save for an existing record is the same, except that each _create callback is replaced by a corresponding _update callback.

Using

 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 

ActiveRecord callbacks from rails console (with 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 ] 
+6
source

Source: https://habr.com/ru/post/920759/


All Articles