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


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
    id: Primary32,
    email: String

  before_validation :clean_up_email

  private def clean_up_email = email.gsub('+', "")

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 ::build.

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
    id: Primary32,
    name: String
  after_save :saved
  after_commit :committed, on: :save

  def saved
    puts "saved"

  def committed
    puts "committed"

user = User.all.first!

User.transaction do = "new name"
  puts "end of transaction"
puts "after transaction"

will ends with next output:

end of transaction
after transaction