ActiveRecord Callbacks: Managing the Workflow of Your Model

Ahmet AYHAN
4 min readMay 23, 2024

--

Hello, I would like to mention ActiveRecord callbacks. This article will help you to understand what ActiveRecord callbacks are, why and how they are used, and their working order.
How should we proceed when using callbacks in this article? Are there any points we should pay attention to? If so, what should we pay attention to when writing? I will share sample codes for various situations.

When developers work on model operations with ActiveRecord, sometimes they need to execute methods or blocks before or after the operations. This mechanism is called ActiveRecord callback.

What are ActiveRecord Callbacks?

Callbacks are special methods that get called at certain moments of an object’s life cycle. Callbacks allow us to run a specific method or block of code in a specific part of the model’s operation. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database. Therefore, it helps us manage business logic and data validation processes or manage records

Why and When to Use Callbacks?

Callbacks allow predetermined actions to occur automatically on a model.
Here are the situations where callbacks are particularly useful:

1- Data validation and Conversion: It may be necessary to validate or transform data before saving. These operations can be done with callbacks such as before_validation or before_save.
2- Managing Relationships: When a model is created, updated or deleted, it may be necessary to update or clear records. After_create, after_update or after_destroy can be used for these operations.
3- Complex business Logic: If you need to perform complex operations before or after model operations, you can do it with callbacks.

How to Use Callbacks?

Callbacks are defined within the model and named according to the event they are associated with.
The order in which callbacks work is very important. It would be more beneficial to use it knowing that it works in a sequence rather than using it randomly.

The general execution order of ActiveRecord callbacks is:
1-) before_validation: Runs before the validation process starts.
2-) after_validation: Runs after the validation process is completed.
3-) before_save: Runs before the record is saved.
4-) before_create: Runs before a new record is created (before it is added to the database)
5-)after_create: Runs after a new record is created.
6-)after_save: Runs after the recording is saved.
7-)before_update: Runs before an existing record is updated.
8-)after_update: Runs after an existing record is updated.
9-)before_destroy: Runs before the record is destroyed.
10-)after_destroy: Runs after the record is deleted.
11-)after_commit: Runs after all database transactions are completed.

For example, when a user is created in a model, we need to convert the user’s email to lowercase and save it without saving it.
Then we need to send an e-mail. If we don’t know the callback order we can write our code as follows:

class User < ApplicationRecord
after_create :send_welcome_email
before_save :normalize_email

private

def send_welcome_email
# Hoş geldiniz e-postası gönder
puts "Welcome email sent to #{self.email}"
end

def normalize_email
# E-posta adresini küçük harfe dönüştür
self.email = email.downcase
puts "Email normalized to #{self.email}"
end
end

Here, we first send an e-mail, then correct the e-mail and save it.
This will cause no e-mail to be sent to the e-mail address entered with capital letters.

Here are correct usage of callback implementations:

Sample Callback Implementations

class Article < ApplicationRecord
after_create :send_notification

private

def send_notification
# Send a notification when a new article is created
puts "New article created: #{self.title}"
end
end
class Order < ApplicationRecord
before_commit :calculate_total_price

private

def calculate_total_price
# Calculate the total price of the order
self.total_price = calculate_price
end

def calculate_price
# Price calculation logic
end
end

We can use statements to run callbacks. Here an example

class Product < ApplicationRecord
after_update :update_inventory, if: :quantity_changed?

private

def update_inventory
# Update product inventory
puts "Inventory updated: #{self.name}"
end
end
class Transaction < ApplicationRecord
around_create :log_transaction

private

def log_transaction
# Log the transaction
puts "Transaction starting..."
yield # Proceed with the transaction
puts "Transaction completed."
end
end

In the examples above, you can see how ActiveRecord callbacks can be used. For example, the after_create callback is used to send a notification when a new article is created, while the around_create callback is used to perform custom actions before and after starting an action.

ActiveRecord callbacks are a powerful tool for managing model workflow and reducing code duplication. However, when used unnecessarily, it can lead to complex code structure, so it should be chosen and implemented carefully.

In this article, we examined what ActiveRecord callbacks are, why they are used, how they are used, with suitable examples. By choosing the right callbacks, you can effectively manage your model workflow and make your code more organized.

--

--