This tutorial aims to provide an in-depth understanding of validating models and using callbacks in Rails. The focus is on data validation before it's saved to the database and triggering actions before or after changes to the Rails objects.
On completing this tutorial, you will be able to:
- Validate data before saving it to the database
- Use callbacks effectively to manage actions on object life cycle events
In Rails, models are used to interact with the database. It's important to ensure that only valid data gets saved. Rails provides several helper methods to check the validity of data. These validations run before Rails saves data to the database.
For example, you can use validates_presence_of :attribute
to ensure that a certain attribute is not empty.
Callbacks are methods that Rails calls at certain moments of an object's life cycle. You can use callbacks to perform logic before or after an object is created, updated, deleted, etc.
For example, before_save :method
would run a certain method before the object is saved.
In this example, we have a User
model with name
, email
, and password
attributes. We want to ensure no user can be saved without these attributes:
class User < ApplicationRecord
validates :name, :email, :password, presence: true
end
Here, validates :name, :email, :password, presence: true
ensures that these fields must be present before a User object is saved.
In the same User
model, let's say we want to downcase the email before saving the user:
class User < ApplicationRecord
validates :name, :email, :password, presence: true
before_save :downcase_email
private
def downcase_email
self.email = email.downcase
end
end
Here, before_save :downcase_email
is called before the user is saved. The downcase_email
method will take the email and convert it to lowercase.
This tutorial covered:
- Validating models: Ensuring data is valid before saving
- Using callbacks: Triggering actions at certain moments of an object's life cycle
Next, consider exploring other types of validations and callbacks. The Rails Guides are a good resource for this.
Create a Product
model with name
and price
attributes. Ensure that the product cannot be saved without a name and that the price is a positive number.
In the Product
model, create a callback that sets a default price if none is provided.
Create a before_save
callback in the User
model that checks if the provided email is in a valid format.
class Product < ApplicationRecord
validates :name, presence: true
validates :price, numericality: { greater_than: 0 }
end
class Product < ApplicationRecord
validates :name, presence: true
validates :price, numericality: { greater_than: 0 }
before_save :default_price
private
def default_price
self.price ||= 10
end
end
class User < ApplicationRecord
validates :name, :email, :password, presence: true
before_save :downcase_email, :validate_email
private
def downcase_email
self.email = email.downcase
end
def validate_email
unless email =~ URI::MailTo::EMAIL_REGEXP
errors.add(:email, 'must be a valid email address')
end
end
end