Jamie Hill
Photo of Jamie Hill

UX Designer, CSS Wizard, Ruby on Rails Developer.

Sexy Validations in Rails 3.0

Update: This patch has been applied but this information is out of date, please see: this new post.
Having had a patch accepted in Rails, I now have the bug (not a bug… the bug for writing patches… anyway).
I have just added this patch to allow for “sexy-migration-esque” validations using the new ActiveModel. Below explains the gist of it:

  class EmailValidator < ActiveRecord::Validator
    def validate
      field = options[:attr]
      record.errors[field] << "is not valid"
        unless record.send(field) =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  # Register the custom validator in an initializer file.
  ActiveModel::Validations.register_validator :email, EmailValidator
  class Person < ActiveModel::Base
    attr_accessor :name, :email
    validates :name, :presence => true, :uniqueness => true, :length => { :maximum => 100 }
    validates :email, :presence => true, :email => true

As with the previous patch I believe this adds even more flexibility which is what Rails 3 is all about. It also allows validators to be shared more easily.
Rails defaults can now also be overridden e.g.

  class RequiredValidator < ActiveRecord::Validator
    def validate
      field = options[:attr]
      record.errors[field] << "Required" if record.send(field).blank?
  ActiveModel::Validations.register_validator :email, RequiredValidator

I would appreciate a +1 on the ticket from anyone who feels this should be in Rails 3.0.