Difference between after_create, after_save and after_commit in rails callbacks

Ruby on-RailsRubyActiverecordCallback

Ruby on-Rails Problem Overview


The difference between after_create, after_save and after_commit in Rails is that:

  • after_save is invoked when an object is created and updated
  • after_commit is called on create, update and destroy.
  • after_create is only called when creating an object

Is this the only difference among those, or are there any other major differences?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

You almost got it right. However there is one major difference between after_commit and after_create or after_save i.e.

In the case of after_create, this will always be before the call to save (or create) returns.

Rails wraps every save inside a transaction and the before/after create callbacks run inside that transaction (a consequence of this is that if an exception is raised in an after_create the save will be rolled back). With after_commit, your code doesn't run until after the outermost transaction was committed. This could be the transaction rails created or one created by you (for example if you wanted to make several changes inside a single transaction). Originally posted here

That also means, that if after_commit raises an exception, then the transaction won't be rolled back.

From M-Dahab's comment: after_commit would run after create, update and destroy. But, you can use on: option to specify which you are interested in. after_commit :some_method, on: :create or even after_commit :some_method, on: [:create, :destroy] or use a block like after_commit(on: :update) do run_method() end.

Solution 2 - Ruby on-Rails

With Order of callbacks

after_create -

Is called after Model.save on new objects that haven‘t been saved yet (no record exists)

after_save -

Is called after Model.save (regardless of whether it‘s a create or update save)

after_commit -

Is called after the database transaction is completed.

Solution 3 - Ruby on-Rails

Also, after_commit will execute even if the record was only touched. This may NOT be what you want. after_save will not run after touch.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHaseeb AhmadView Question on Stackoverflow
Solution 1 - Ruby on-RailsDushtView Answer on Stackoverflow
Solution 2 - Ruby on-RailsArvind singhView Answer on Stackoverflow
Solution 3 - Ruby on-RailshellionView Answer on Stackoverflow