Take me home

Creating your own validations

Written by August Lilleaas, published July 03, 2009

There are many different methods for creating your own, custom validations in Rails. Here’s some of them:

class Post < ActiveRecord::Base
  validate :my_custom_validation, :on => :create
  
  validate do |record|
    record.errors.add_to_base("This sucks.") if record.ponies?
  end
  
  def ponies?
    false # do something real here.
  end
  
  private
  
  def my_custom_validation
    errors.add.to_base("I refuse to be saved!") if my_condition?
  end
end

validates_each

You can use validates_each to run the same validation code on multiple attributes.

class User < ActiveRecord::Base
  validates_each(:home_email, :job_email) do |record, attribute, value|
    if value !~ /my fancy email regexp/
      record.errors.add(attribute, "My error message!")
    end
  end
end

Custom validates_foo methods

In Rails’ internals, validates_each is used in all the validation methods. validates_each will handle generic options such as :on => :create, :if => proc { ... }, and so on.

# lib/validates_email.rb
class ActiveRecord::Base
  def self.validates_email(*args)
    validates_each(*args) do |record, attribute, value|
      if value !~ /my fancy email regexp/
        record.errors.add(attribute, "is not a valid e-mail address")
      end
    end
  end
end
 
# config/initializers/[anything].rb
require "validates_email"

This code provides a validates_email method you can use in your model, alongside validates_length_of and friends.

class Contact < ActiveRecord::Base
  validates_email :home_email, :work_email, :on => :create
end

Questions or comments?

Feel free to contact me on Twitter, @augustl, or e-mail me at august@augustl.com.