What is the best/easy way to validate an email address in Ruby?

Ruby on-RailsRubyRuby on-Rails-3

Ruby on-Rails Problem Overview


What is the best/easy way to validate an email address in ruby (on the server side)?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

You could look whether or not it matches a regexp like the one used in this Rails validator:

validates_format_of :email,:with => /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/

But if you use Devise, simply do:

validates_format_of :email,:with => Devise::email_regexp

Source: http://lindsaar.net/2008/4/14/tip-4-detecting-a-valid-email-address

Edit 1:

useful website for tests: http://www.rubular.com/

Solution 2 - Ruby on-Rails

In Ruby? The same way as in any language.

Send a confirmation email to the address with a link that the recipient has to click before the email address is considered fully validated.

There are any number of reasons why a perfectly formatted address may still be invalid (no actual user at that address, blocked by spam filters, and so on). The only way to know for sure is a successfully completed end-to-end transaction of some description.

Solution 3 - Ruby on-Rails

I know that this is a old question but I was looking for a simple to way to do this. I came across a email_validator gem this is really simple to set up and use.

as a validator

validates :my_email_attribute, :email => true

Validation outside a model

EmailValidator.valid?('[email protected]') # boolean

I hope that this help everyone.

Happy Codding

Solution 4 - Ruby on-Rails

validates :email, presence: true, format: /\w+@\w+\.{1}[a-zA-Z]{2,}/

checks that email field is not blank and that one or more characters are both preceding the '@' and following it

Added specificity, any 1 or more word characters before an the @and any 1 or more word character after and in between specifically 1 . and at least 2 letters after

Solution 5 - Ruby on-Rails

Shortcut Form:

 validates :email, :format => /@/

Normal Form (Regex) :

validates :email, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }

Source: Validator Class

Solution 6 - Ruby on-Rails

You can use

<%=email_field_tag 'to[]','' ,:placeholder=>"Type an email address",:pattern=>"^([\w+-.%]+@[\w-.]+\.[A-Za-z]{2,4},*[\W]*)+$",:multiple => true%>

Solution 7 - Ruby on-Rails

Since the main answer's blog site was down, here is the snippet of code from that site via nice cacher or gist:

# http://my.rails-royce.org/2010/07/21/email-validation-in-ruby-on-rails-without-regexp/
class EmailValidator < ActiveModel::EachValidator
  # Domain must be present and have two or more parts.
  def validate_each(record, attribute, value)
    address = Mail::Address.new value
    record.errors[attribute] << (options[:message] || 'is invalid') unless (address.address == value && address.domain && address.__send__(:tree).domain.dot_atom_text.elements.size > 1 rescue false)
  end
end

Solution 8 - Ruby on-Rails

You can take reference from https://apidock.com/rails/ActiveModel/Validations/HelperMethods/validates_format_of

> validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i

Solution 9 - Ruby on-Rails

If you are using Rails/Devise - addition to @apneadiving`s answer -

validates_format_of :email,:with => Devise::email_regexp

Devise::email_regexp is taken from config/initializers/devise.rb

config.email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/

Solution 10 - Ruby on-Rails

Send a confirmation mail , and I will usualy use this validator ... D.R.Y.

# lib/email_validator.rb
class EmailValidator < ActiveModel::EachValidator

  EmailAddress = begin
    qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
    dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
    atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' +
      '\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
    quoted_pair = '\\x5c[\\x00-\\x7f]'
    domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
    quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
    domain_ref = atom
    sub_domain = "(?:#{domain_ref}|#{domain_literal})"
    word = "(?:#{atom}|#{quoted_string})"
    domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
    local_part = "#{word}(?:\\x2e#{word})*"
    addr_spec = "#{local_part}\\x40#{domain}"
    pattern = /\A#{addr_spec}\z/
  end

  def validate_each(record, attribute, value)
    unless value =~ EmailAddress
      record.errors[attribute] << (options[:message] || "is not valid") 
    end
  end
  
end

in your model

validates :email , :email => true

or

 validates :email, :presence => true, 
                :length => {:minimum => 3, :maximum => 254},
                :uniqueness => true,
                :email => true

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRanView Question on Stackoverflow
Solution 1 - Ruby on-RailsapneadivingView Answer on Stackoverflow
Solution 2 - Ruby on-RailspaxdiabloView Answer on Stackoverflow
Solution 3 - Ruby on-RailsMZaragozaView Answer on Stackoverflow
Solution 4 - Ruby on-RailspartydogView Answer on Stackoverflow
Solution 5 - Ruby on-RailsOmer AslamView Answer on Stackoverflow
Solution 6 - Ruby on-RailsakshayView Answer on Stackoverflow
Solution 7 - Ruby on-RailstoobulkehView Answer on Stackoverflow
Solution 8 - Ruby on-RailsKanmaniselvanView Answer on Stackoverflow
Solution 9 - Ruby on-RailsYurii VerbytskyiView Answer on Stackoverflow
Solution 10 - Ruby on-RailsandreaView Answer on Stackoverflow