after_create vs after_save vs after_commit

Callbacks are useful tools to use in Rails applications.

The ones I tend to use most are ones that run before or after certain actions are taken upon an ActiveRecord model. Some of the common ones you may see in a typical Rails codebase are before_save, before_create, after_create, and after_save. In this blog post, I’ll be writing specifically about the difference between the after_create and after_save, and then throw after_commit to the mix since it can be preferable to use after_commit in specific situations.

First, let’s take a look at the difference between after_create, after_save, and after_commit.


after_create

This is called after ActiveRecord::Base.save is called on new objects that haven’t been saved yet (meaning that no record exists in the database)

after_save

This is the same thing as after_create but is called whether the object is a new or an existing record in the database.

after_commit

This is called after the database transaction has completed.


Now, the part about “after the database transaction has completed” for after_commit is important because this will determine whether you will prefer after_commit vs the after_create or after_save. Basically what this means is that after_create or after_save can still run before the changes are actually saved to the database, meaning the database can raise an error if the data you want to commit to the database violates your database constraints (like a uniqueness constraint violation). Thus, in certain situations where you want to work with data that you are sure that has been written to the database, after_commit is preferable to after_create or after_save.

This is one of those “gotchas” about various callback options a developer may have that’s not blatantly obvious. Choosing the right callback can save you a lot of headache in creating accidental bugs.