Ruby on Rails ActiveRecord Validations
Eapen Zacharias
Posted on July 5, 2022
Validations allow us to make sure that data meets a set of requirements before it's saved to the database. You can think of them as rules that our data must follow. It is always a good practice to check the validations from the models to make our models smarter by telling them about what should be considered valid data in the database and also regardless of where we're submitting data from the application, it'll still follow the rules.
Built in Validation Methods
Rails provided many inbuilt validation helpers which covers most use cases when you are building an app. Here are the most important ones:
# validates_presence_of validates the attribute is not blank
validates_presence_of :atrr_name
# Validates_length_of check length requirements of the attribute
validates_length_of :attr_name, :within => 3..40
validates_length_of :attr_name, :is => 40
validates_length_of :attr_name, :minimum => 10, :maximum => 50
-
:minimum
- The attribute cannot have less than the specified length. -
:maximum
- The attribute cannot have more than the specified length. -
:in
(or:within
) - The attribute length must be included in a given interval. The value for this option must be a range. -
:is
- The attribute length must be equal to the given value.
# Validates_numecality_of check if the attribute is a number or not
validates_numericality_of :height, :greater_than => 3.0
validates_numericality_of :height, :less_than => 100
validates_numericality_of :height, :equal_to => 3.0
validates_numericality_of :height, :greater_than_or_equal_to => 3.0
validates_numericality_of :height, :less_than_or_equal_to => 100
-
:greater_than
- Specifies the value must be greater than the supplied value. The default error message for this option is "must be greater than %{count}". -
:greater_than_or_equal_to
- Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "must be greater than or equal to %{count}". -
:equal_to
- Specifies the value must be equal to the supplied value. The default error message for this option is "must be equal to %{count}". -
:less_than
- Specifies the value must be less than the supplied value. The default error message for this option is "must be less than %{count}". -
:less_than_or_equal_to
- Specifies the value must be less than or equal to the supplied value. The default error message for this option is "must be less than or equal to %{count}". -
:other_than
- Specifies the value must be other than the supplied value. The default error message for this option is "must be other than %{count}". -
:in
- Specifies the value must be in the supplied range. The default error message for this option is "must be in %{count}". -
:odd
- Specifies the value must be an odd number if set to true. The default error message for this option is "must be odd". -
:even
- Specifies the value must be an even number if set to true. The default error message for this option is "must be even".
# Validates_inclusion_of checks to see if an attribute is in a list of choices, and you need to provide it an array or a range for it to look in.
# Validates_exclusion_of checks to see if it is not present in the list of choices
validates_inclusion_of :status, :in => ['new', 'created', 'approved', 'deleted']
validates_exclusion_of :status, :in => [55, 66, 77]
# Validates_format_of check if it matches regex
validates_format_of :zipcode, :with => /\d{6}/
# Validates_uniqueness_of is going to make sure that an attribute is not already in the database.
validates_uniqueness_of :user_name, :case_sensitive => false
validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id]
# Making sure that a teacher can only be on the schedule once per semester for a particular class.
# Validates_confirmation_of Encapsulates the pattern of wanting to validate a password or email address field with a confirmation
validates_confirmation_of :user_name, :password
validates_confirmation_of :email_address,
message: 'should match confirmation'
# The added password_confirmation attribute is virtual; it exists only as an in-memory attribute for validating the password. To achieve this, the validation adds accessors to the model for the confirmation attribute.
# NOTE: This check is performed only if password_confirmation is not nil. To require confirmation, make sure to add a presence check for the confirmation attribute:
# Validates_associated is used to check associations with other models, so it check the validity of the associated model
class Library < ApplicationRecord
has_many :books
validates_associated :books
end
# Validates_acceptance_of is typically used when the user needs to agree to your application's terms of service, confirm that some text is read, or any similar concept. This method creates a virtual attribute and it is not saved to the database.
validates_acceptance_of :terms_of_service
# Validate multiple parameters in one go
validates :attr_name,
:presence => boolean,
:numericality => boolean,
:length => option_hash,
:format => {:with => regex},
:inclusion => {:in => range_or_array},
:exclusion => {:in => range_or_array},
:acceptance => boolean,
:uniqueness => boolean,
:confirmation => boolean
Custom Validations
Most of the time, the built-in validations that Ruby on Rails gives you, are going to be enough to help you keep your data under control. But every now and then there's some special cases that come up where they're not enough and we'd like to be able to write our own custom validations. Well, Ruby on Rails lets us do that too.
validate :custom_method
private
def custom_method
if test_case
error.add(:attribute, "error message")
# You can use :base as attribute name if the error is not specific to an attribute
end
end
Skipping Validation
Skipping validations bypasses the data rules that you've established for the application and it should be done with extreme caution because you could actually introduce invalid data into the database and that could have severe consequences to the application.
Here are few ways to do that.
record.save(validate: false)
record.update_columns(:name => value) # This directly updates the database
record.update_column(:name, value)
When you have an active record relation, you've built up like a relation defined using where clauses to find the record you want, then you can call, update all and provide a hash of values and it will go and do update columns ****on all of those records without actually finding them.
relation.update_all(:name => value)
Thanks For Reading, Follow Me For More
Share your suggestions, doubts and feedback in the comments section!
Posted on July 5, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.