Validations Overview

Valid data is critical to ensure stability in your application. An application assumes data will have certain characteristics when performing operations on them. A developer can make certain the data is reliable before being entered or updated in the database. Active Record can validate contents of a model object automatically when an object is saved. A developer can also check the validity of an object before it is saved too. Validation rules can be defined to check validity at creation or update of an object.

A peek into the object life cycle

Validation takes place when you save an object. If an object is new and you save it then you will create that record (insert into the database). If an object exists in the database and you save it then you will update that record. Either way when you save an object validation will occur to ensure proper data. Another way to check for validity of your object is to call the valid? method. You can call this method anytime you want to check the validity of your object.

Active Record Validation Helpers

validates_acceptance_of

Validates that a checkbox has been checked.
class User < ActiveRecord::Base
  validates_acceptance_of :terms_of_service, :message=>"Please accept the terms to create your user account" 
end

validates_associated

Performs validation on associated objects.
class User < ActiveRecord::Base
  has_many :books
  validates_associated :books
end

validates_confirmation_of

Validates a field and its verified field have the same content.

A user form may ask for a password and confirmation like this:
<%= password_field "user", "password" %><br /> 
<%= password_field "user", "password_confirmation" %><br />

Validation defined in the model:
class User < ActiveRecord::Base
  validates_confirmation_of :password
end

validates_exclusion_of

Validates that attributes are not in a set of values.
class Book < ActiveRecord::Base
  validates_exclusion_of :published_year, :in => 1900..2009, :message => "must be a newly published book" 
end

validates_inclusion_of

Validates that attributes belong to a set of values (represented by an enumerable object)
class Review < ActiveRecord::Base
  validates_inclusion_of :rating, :in => 1..5, :message => "must select a rating between 1 and 5" 
end

validates_format_of

Validates that attributes against a pattern.
class User < ActiveRecord::Base
  validates_format_of :email, :with => /\A([\w\.\-\+]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
end

validates_length_of

Validates the length of an attribute value.
class User < ActiveRecord::Base
  validates_length_of :name, :minimum => 3
  validates_length_of :password, :in => 6..20
end

class Book < ActiveRecord::Base
  validates_length_of :published_year, :maximum => 4
end

validates_numericality_of

Validates that attributes are valid numerical values. You can also check an attribute to be a whole number by using the integer_only option.
class Book < ActiveRecord::Base
  validates_numericality_of :published_year, :only_integer => true
end

validates_presence_of

Validates that attributes are not empty (nil or blank)
class User < ActiveRecord::Base
  validates_presence_of :name, :login, :email
end

validates_uniqueness_of

Validates that attributes are unique for all models of the same type.
class User < ActiveRecord::Base
  validates_uniqueness_of :login
end

Conditional Validation

The validation helper methods can use an optional

:if
and
:unless
that will determine whether a validation will be run.

There are three types of arguments that can supplied: symbol, string, and proc.

Symbol example

class User < ActiveRecord::Base
  validates_confirmation_of :password, :unless => :password_blank?

  def password_blank?
    password.blank?
  end
end

String example

class User < ActiveRecord::Base
  validates_confirmation_of :password, :unless => "password.blank?" 
end

Proc example

class User < ActiveRecord::Base
  validates_confirmation_of :password, :unless => Proc.new { |a| a.password.blank? }
end

Getting to know the Validation errors

Quite simply, validation problems are otherwise known as errors. Every Active Record object has a collection of errors accessed via the errors attribute. When an object is valid the errors collection is empty.
You can check for errors by calling valid? / invalid? or look for specific error messages on attributes by calling on.

book = Book.first
book.valid?
book.errors.on(:title) #returns nil if no error message otherwise error string

errors.add_to_base

Custom error messages not related to any one attribute can be added to the error collection. The developer can design validity of an object based off of one or more attribute's values if desired.
class User < ActiveRecord::Base
  def please_validate_me
    errors.add_to_base("The user is invalid because you did something crazy scary!")
  end
end

errors.add

Lets you add error messages specific to an attribute. The error message is assumed to be appended to a capitalized string of the attribute name.
class User < ActiveRecord::Base
  ...
  def please_validate_me
    errors.add(:age, "must be at least 21")
  end
  ...
end

user = User.first
user.valid? #assume invalid
user.errors.on(:age) # => "must be at least 21" 
user.errors.full_errors # =>"Age must be at least 21" 

errors.clear

Let's you clear the errors collection.

Additional resources

  1. Rails Guides: Active Record Validations and Callbacks

Also available in: HTML TXT