Callbacks (callback functions) are a common way to execute custom code at certain points in the life cycle of an Active Record object, such as right before it is created, after it is saved, or after it is destroyed. For example, it can be useful for transferring all characters from a user's email to lowercase when creating his or her account. Callbacks are a way of saying something like "Hey Active Record, when you finish creating a new user object, let me know so that I can run this method before anything else happens."
Here is a list of the life cycle events:
- Initialization - when the object was first created in memory.
- Validation - This happens when you try to save an object, or when you manually call a #valid? method.
- Save - saves a newly made object to the database.
- Create - creates and saves a new object.
- Update - updates an existing object.
- Destroy - deletes an existing object from the database.
As a rule, you have a choice of 3 callbacks. Not all objects’ life cycle steps support the full set of callbacks, but the main ones are:
- before_ - starts the method before the specified action
- after_ - starts the method after the specified action
- around_ - In this case, you can execute the code both before and after the action, so that YOU can decide at what point the initial action will be performed. This is not used very often.
Using callbacks
To use a callback, you will need to register it at the top of your model using the appropriate method. You can either add a code block or pass another method as a parameter to the callback function.
# app/models/song.rb
class Song < ActiveRecord::Base
after_create do |song|
puts "Just created a song"
end
before_create :song_created
private
def song_created
puts "about to create #{song.title}"
end
end
Specifying Callback Features
Callbacks allow you to narrow down the list of actions in which the callbacks will run. If you just want to start a callback when a certain controller action calls it, use on: .
...
before_validation :normalize_name, on: :create
private
def normalize_name
self.name = name.downcase.titleize
end
...
You can also use conditional logic options :if and :unless to test the method before starting the callback. For example:
...
before_save :normalize_card_number, if: :paid_with_card?
private
def paid_with_card?
true
end
...
Top comments (0)