Ruby on Rails - Validation



It is important that the state of an object of Active Record class is validated before saving the same in the underlying database. This is essential to ensure the integrity of the data. For example, your model might have email as one of the attributes. It must be ensured that the user enters a valid email address before saving the record.

Rails provides model-level validations to ensure that only valid data is saved into your database. There are many built-in helpers, and you can create your own validation methods as well.

Rails runs the validations before saving a new object or updating an existing object to the database. If any validations fail, the object will be marked as invalid and Active Record will not perform the INSERT or UPDATE operation.

Validation takes place when any of the following methods of Active Record are called:

  • create
  • create!
  • save
  • save!
  • update
  • update!

Methods with exclamation mark(!) at the end raise an exception when a record is invalid.

You can also run the save method by skipping the validation.

save(validate: false)

Let us first declare a Person model as below:

rails generate model Person name:string age: integer

Then migrate this model

rails db:migrate

In the person.rb, add the validation rule aas:

class Person < ApplicationRecord validates :name, presence: true end

Open the Ruby console, and declare a Person object

library(dev)> p = Person.new => #<Person:0x00000243d3c9af40 ... Check if the object is valid library(dev)> p.valid? => false

Declare another object and check the validity

library(dev)> p = Person.new(name:"Ravi", age:21) => #<Person:0x00000243cf159ec8 ... library(dev)> p.valid? => true

Modify the model to add another validity rule, age shoulf be numeric and greater than 0.

class Person < ApplicationRecord validates :name, presence: true validates :age, numericality: { greater_than: 0 } end

If you declare an object as follows, and check if it is valid

library(dev)> p = Person.new(name:"Ravi", age:0) => #<Person:0x0000026df640c228 ... library(dev)> p.valid? => false

The save method on invalid object returns false

library(dev)> p.save => false

If you try to skip the validation while running the save operation, Rails throws an error.

library(dev)> p.save! (library):4:in `<main>': Validation failed: Age must be greater than 0 (ActiveRecord::RecordInvalid)

Validates Method

You can add validations to a model using the validates method inside the model class. This ensures that data meets certain conditions before being saved to the database.

Iin Rails, validates is a class method, provided by ActiveModel::Validations. It is used to declare validation rules for a model's attributes.

class Person < ApplicationRecord validates :name, presence: true end

The method should have the parameters:

  • *attributes − Takes one or more attribute names (like :title).
  • **options − Takes a hash of validation rules (presence: true, length: { minimum: 3 }, etc.).

Validation Helpers

There are many pre-defined validation helpers to be used inside your class definitions. Each helper accepts an arbitrary number of attribute names. The :on and :message options define when the validation should be run and what is the error message when the validation fails.

Presence Validation

This validation ensures that a particular field is not empty. In the above Person model, name cannot be empty.

class Person < ApplicationRecord validates :name, presence: true end

Length Validation

This validation is commonly used to restrict the length of a string field. For example, if the Person model has a password field and you want to ensure it to be at least 8 characters long, you would write the following code −

class Person < ApplicationRecord validates :password, length: { minimum: 8 } end

The other length constraint options are:

  • :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.
  • :is – The attribute length must be equal to the given value.

Numericality Validation

Use this validation to ensure that a particular field is a number. For example,

class person < ApplicationRecord validates :age, numericality: { greater_than_or_equal_to: 18 } end

This will ensure the age field is a number greater than or equal to 18.

Following options can be used to specify the validation rules:

  • :greater_than – Specifies the value must be greater than the supplied value.
  • :greater_than_or_equal_to – Specifies the value must be greater than or equal to the value.
  • :equal_to – Specifies the value must be equal to the supplied value.
  • :less_than – Specifies the value must be less than the supplied value.
  • :less_than_or_equal_to – Specifies the value must be less than or equal to the supplied value.
  • :other_than – Specifies the value must be other than the supplied value.
  • :in – Specifies the value must be in the supplied range.
  • :odd – Specifies the value must be an odd number.
  • :even – Specifies the value must be an even number.
  • :only_integer – specifies the value "must be an integer".

Confirmation Validation

You should use this helper when you have two text fields that should receive exactly the same content. For example, the Person model has a field named as email and you want to confirm an email address.

class Person < ApplicationRecord validates :email, confirmation: true end

Comparison Validation

This validation helps you perform a comparison between any two comparable values.

class Person < ApplicationRecord validates :age, comparison: { greater_than: :min_age } end

Options available:

  • :greater_than - Specifies the value must be greater than the supplied value.
  • :greater_than_or_equal_to - Specifies the value must be greater than or equal to the supplied value.
  • :equal_to - Specifies the value must be equal to the supplied value.
  • :less_than - Specifies the value must be less than the supplied value.
  • :less_than_or_equal_to - Specifies the value must be less than or equal to the supplied value
  • :other_than - Specifies the value must be other than the supplied value.

Inclusion Validation

This helper validates that the attributes' values are included in a given set. In fact, this set can be any enumerable object.

class Student < ApplicationRecord validates :subject, inclusion: { in: %w(Phy Che Maths } end

Exclusion Validation

This helper is the opposite of inclusion as it validates that the attributes' values are not included in a given set.

Uniqueness Validation

This validator ensures that the attribute's value is unique right before the object gets saved.

class Person < ApplicationRecord validates :RollNo, uniqueness: true end

Multiple Validations

You can use multiple validations on a single field by chaining validations together.

validates :userid, :presence => true, :length => length: {minimum: 10, maximum: 50}, :uniqueness => true, :confirmation => true

Validation methods with older Rails syntax (before Rails 3) are still supported for backward compatibility. Examples:

  • validates_presence_of
  • validates_numericality_of
  • validates_length_of
  • validates_inclusion_of
  • validates_confirmation_of

Custom Validation

In addition to the built-in validation methods, Rails also allows you to create custom validations. For example, if you want to ensure that the name attribute in the Person model is always capitalized, you could write a custom validation method:

class Person < ApplicationRecord validate :CustomValidator private def CustomValidator errors.add(:name, "must be capitalized") unless name.nil? || name == name.capitalize end end
Advertisements