Nerd For Tech
Published in

Nerd For Tech

ActiveRecord Callbacks with Rails

Can you imagine accidentally saving bad data into your database? If bad data were to get into your database, you could add additional logic into your controllers to handle them. But what if we could somehow handle that before an object is created?

Along with validations, using callbacks will prevent bad data from being inserted into your database.

What is a callback?

A callback is a method that gets called during an object’s specific moment in its lifecycle. An object’s lifecycle is from its creation to its destruction In-between the creation and destruction of an object will be the READ and UPDATE moments.

Step 1

In order to use a callback, we have to define one in a model that will be using that specific callback. For example, if we have a web application that lets people create accounts, we might have something like:

class User < ApplicationRecord
validates_presence_of :first_name, :last_name
private
def ensure_name_is_titlecase
self.first_name.titlecase
self.last_name.titlecase
end
end

Sometimes users could accidentally type their names with lowercase letters. Then on their homepage, we could try to welcome the user but the user sees that their name is lowercased! We would want a method to prevent that embarrassment.

Step 2

After defining the method that we need, we would let ActiveRecord know when to execute ensure_name_is_titlecase.

class User < ApplicationRecord
validates_presence_of :first_name, :last_name
before_validation :ensure_name_is_titlecase
private
def ensure_name_is_titlecase
self.first_name.titlecase
self.last_name.titlecase
end
end

The macro, before_validation suggests that the method that it takes as an input will be executed every time before there is a validation.

Here is a list of common ActiveRecord methods that will trigger a validation:

  • save
  • save!
  • update
  • update!
  • valid?

With before_validation :ensure_name_is_titlecase, the ensure_name_is_titlecase method will run before every validation method.

Step 3

But what if we don’t want our program to waste time running certain callbacks? We could specify which lifecycle events to run the callbacks in addition to just before any methods that validates!

class User < ApplicationRecord
validates_presence_of :first_name, :last_name
before_validation :ensure_name_is_titlecase, on: [ :create, :update ]
private
def ensure_name_is_titlecase
self.first_name.titlecase
self.last_name.titlecase
end
end

In this snippet, we specify that we want the callback to only run on the create and update lifecycle events. This way, we won’t run unnecessary methods!

Common Callback Macros

When Creating an Object

  • before_validation
  • after_validation
  • before_save
  • after_save
  • before_create
  • after_create

When Updating an Object

  • before_validation
  • after_validation
  • before_save
  • after_save
  • before_update
  • after_update

When Destroying an Object

  • before_destroy
  • after_destroy

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store