We get into the situation where incident object need to created/saved with before_save and after_create/after_commit.
first attempt [ incident object with before_save and after_create]
incident have an attribute called status.
before_save
def build_incident_logs
self.event_logs.build if status_changed?
end
incident object
incident.save
after_create
def update_attribute_of_incident
self.attribute_one = value
binding.pry
self.save!
end
a.Start the server begin the process, first it comes to before save and build the incident logs.
b.Then incident will be created.
c. After create is called and while trying to update attribute of incident, before save is called again. Now code inside before_save look for status changes.
4. All this happen inside same transaction.
5. So self.id_was nil. Again it will create an duplicate data in incident logs
I have attached the screen shot of this for better understand.
Second attempt [ incident object with before_save and after_commit]
Now change after_create to after_commit
before_save
def build_incident_logs
self.event_logs.build if status_changed?
end
incident object
incident.save
after_commit
def update_attribute_of_incident
self.attribute_one = value
binding.pry
self.save!
end
a.Start the server begin the process, first it comes to before save and build the incident logs.
b.Then incident will be created.
c. After create is called and while trying to update attribute of incident, before save is called again. Now code inside before_save look for status changes.
4. Because of after_commit, it will start the new transaction and previous transaction was closed.
5. Status is available.
6. If i request for self.id_was some_id (eg:34). so no duplicate data is created at incident logs.
Conclusion:
Above content will helpful to pick the right call backs based on requirement. after_create will look into same transaction but after_commit will begins from new transaction .
Tuesday, 14 July 2015
Choose the right call backs in rails. (an example by comparing after_create and after_commit)
Subscribe to:
Posts (Atom)