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
end
end
# 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
end
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?
end
end
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.