Take me home

Creating your own validations

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.