ActiveRecord Callbacks: Managing the Workflow of Your Model
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.