Model callbacks
Models callbacks let you define logic that is triggered before or after a record's state alteration. They are methods that get called at specific stages of a record's lifecycle. For example, callbacks can be called when model instances are created, updated, or deleted.
This documents covers the available callbacks and introduces you to the associated API, which you can use to define hooks in your models.
Overview
As stated above, callbacks are methods that will be called when specific events occur for a specific model instance. They need to be registered explicitly as part your model definitions. There are many types of of callbacks, and it is possible to register "before" or "after" callbacks for most of these types.
Registering a callback is as simple as calling the right callback macro (eg. #before_validation
) with a symbol of the name of the method to call when the callback is executed. For example:
class User < Marten::Model
field :id, :big_int, primary_key: true, auto: true
field :username, :string, max_size: 64, unique: true
before_validation :ensure_username_is_downcased
private def ensure_username_is_downcased
self.username = username.try(&.downcase)
end
end
In the above snippet, a before_validation
callback is registered to ensure that the username
of a User
instance is downcased before any validation.
This technique of callback registration is shared by all types of callbacks.
It should be noted that the order in which callback methods are registered for a given callback type (eg. before_update
) matters: callbacks will be called in the order in which they were registered.
Available callbacks
after_initialize
after_initialize
callbacks are called right after a model instance is initialized. They will be called automatically when new model instances are initialized through the use of new
or when records are retrieved from the database.
before_validation
and after_validation
before_validation
callbacks are called before running validation rules for a given model instance while after_validation
callbacks are executed after. They can be used to sanitize model instance attributes for example.
The use of methods like #valid?
or #invalid?
, or any other methods involving validations (#save
, #save!
, #create
, or #create!
), will trigger validation callbacks. See Model validations for more details.
before_create
and after_create
before_create
callbacks are called before a new record is inserted into the database. after_create
callbacks are called after a new record has been created at the database level.
The use of the #save
method (or #save!
) on a new model instance will trigger the execution of creation callbacks. The use of the #create
/ #create!
methods will also trigger these callbacks.
before_update
and after_update
before_update
callbacks are called before an existing record is updated while after_update
callbacks are called after.
The use of the #save
method (or #save!
) on an existing model record will trigger the execution of update callbacks.
before_save
and after_save
before_save
callbacks are called before a record (existing or new) is saved to the database while after_save
callbacks are called after.
The use of the #save
/ #save!
and the #create
/ #create!
methods will trigger the execution of save callbacks.
before_save
and after_save
are called for both new and existing records. before_save
callbacks are always executed before before_create
or before_update
callbacks. after_save
callbacks on the other hand are always executed after after_create
or after_update
callbacks.
before_delete
and after_delete
before_delete
callbacks are called before a record gets deleted while after_delete
callbacks are called after.
The use of the #delete
method will trigger these callbacks.
after_commit
after_commit
callbacks are called after a record is created, updated, or deleted, but only after the corresponding SQL transaction has been committed to the database (which isn't the case for other after_*
callbacks - See Transactions for more details). For example:
after_commit :do_something
As mentioned previously, by default such callbacks will run in the context of record creations, updates, and deletions. That being said it is also possible to associate these callbacks with one or more specific actions only by using the on
argument. For example:
after_commit :do_something, on: :create # Will run after creations only
after_commit :do_something, on: :update # Will run after updates only
after_commit :do_something, on: :update # Will run after saves (creations or updates) only
after_commit :do_something, on: :delete # Will run after deletions only
after_commit :do_something_else, on: [:create, :delete] # Will run after creations and deletions only
The actions supported by the on
argument are create
, update
, save
, and delete
.
after_rollback
after_rollback
callbacks are called after a transaction is rolled back when a record is created, updated, or deleted. For example:
after_rollback :do_something
As mentioned previously, by default such callbacks will run in the context of record creations, updates, and deletions. That being said it is also possible to associate these callbacks with one or more specific actions only by using the on
argument. For example:
after_rollback :do_something, on: :create # Will run after rolled back creations only
after_rollback :do_something, on: :update # Will run after rolled back updates only
after_rollback :do_something, on: :update # Will run after rolled back saves (creations or updates) only
after_rollback :do_something, on: :delete # Will run after rolled back deletions only
after_rollback :do_something_else, on: [:create, :delete] # Will run after rolled back creations and deletions only
The actions supported by the on
argument are create
, update
, save
, and delete
.