In Rails 3.0, you can use custom validator in your active_record model.
So I wanted to manage email validations without regexp matching like others do.
I find a new way to make this work thanks to ruby mail gem, a dependency of Rails 3.0
class User < ActiveRecord::Base validates :email, :presence => true, :email => true end
Just put a file in app/validators/email_validator.rb
require 'mail' class EmailValidator < ActiveModel::EachValidator def validate_each(record,attribute,value) begin m = Mail::Address.new(value) # We must check that value contains a domain and that value is an email address r = m.domain && m.address == value t = m.__send__(:tree) # We need to dig into treetop # A valid domain must have dot_atom_text elements size > 1 # user@localhost is excluded # treetop must respond to domain # We exclude valid email values like <user@localhost.com> # Hence we use m.__send__(tree).domain r &&= (t.domain.dot_atom_text.elements.size > 1) rescue Exception => e r = false end record.errors[attribute] << (options[:message] || "is invalid") unless r end end
No regexp !! And beautiful !!
Here is the version without activerecord
require 'rubygems' require 'active_model' require 'active_support/all' require 'active_model/validations' require 'mail' class EmailValidator < ActiveModel::EachValidator def validate_each(record,attribute,value) begin m = Mail::Address.new(value) # We must check that value contains a domain and that value is an email address r = m.domain && m.address == value t = m.__send__(:tree) # We need to dig into treetop # A valid domain must have dot_atom_text elements size > 1 # user@localhost is excluded # treetop must respond to domain # We exclude valid email values like <user@localhost.com> # Hence we use m.__send__(tree).domain r &&= (t.domain.dot_atom_text.elements.size > 1) rescue Exception => e r = false end record.errors[attribute] << (options[:message] || "is invalid") unless r end end class Person include ActiveModel::Validations attr_accessor :name, :email validates :name, :presence => true, :length => { :maximum => 100 } validates :email, :presence => true, :email => true end

#1 by Sohan on July 21, 2010 - 16:31
Your post has been linked at the Drink Rails blog as one of the top ruby on rails blogs of the day.
#2 by Hallelujah on July 21, 2010 - 18:07
Thanks a lot