Callbacks
During the normal operation of your application, objects may be created, updated, and destroyed. Jennifer provides hooks into this object life cycle so that you can control your application and its data.
Callbacks allow you to trigger logic before or after an alteration of an object’s state.
Callbacks overview
Registration
In order to use available callbacks, you need to define them. To do this implement callback as instance method and use macro to register it as callback:
class User < Jennifer::Base::Model
mapping(
id: Primary64,
email: String
)
before_validation :clean_up_email
private def clean_up_email
self.email = email.gsub('+', "")
end
end
Available callbacks
Here is a list with all the available callbacks, listed in the same order in which they will get called during the respective operations:
Creating new object
before_validation
after_validation
before_save
before_create
after_create
after_save
after_commit
/after_rollback
Updating existing object
before_validation
after_validation
before_save
before_update
after_update
after_save
after_commit
/after_rollback
Destroying an object
before_destroy
after_destroy
after_commit
/after_rollback
Invoking callbacks
The following methods trigger callbacks:
- validate!
- valid?
- create
- create!
- destroy
- destroy_without_transaction
- save
- save!
- save_without_transaction
- update
- update!
The after_initialize
callback is triggered each time record is initialized using method .new
.
Skipping callbacks
The following methods allows to skip some callbacks or process without them:
- validate
- invalid?
- save(skip_validation: true)
- destroy_without_transaction (no transaction callback will be triggered)
- save_without_transaction (no transaction callback will be triggered)
- update_column
- update_columns
- delete
- modify
- increment
- decrement
Carefully use this methods because otherwise you might get invalid data in a db.
Stopping execution
Raising ::Jennifer::Skip
exception inside of any callback will stop further callback invoking; such behavior in the any before
callback stops current action from being processed.
Transaction callbacks
There are 2 additional callbacks that are triggered right after database transaction completion: after_commit
and after_rollback
. The main difference of these callbacks is they will be executed only after top level transaction will be completed (committed or rolled back) - instead invoking just in place. Also they expect context to be invoked on: create, save, update or destroy. E.g.:
class User < Jennifer::Model::Base
mapping(
id: Primary64,
name: String
)
after_save :saved
after_commit :committed, on: :save
def saved
puts "saved"
end
def committed
puts "committed"
end
end
user = User.all.first!
User.transaction do
user.name = "new name"
user.save
puts "end of transaction"
end
puts "after transaction"
will ends with next output:
saved
end of transaction
committed
after transaction