What Is the Best/How to Validate an Email Address in Ruby

Ruby Email validation with regex


TL;DR:

credit goes to @joshuahunter (below, upvote his answer). Included here so that people see it.

URI::MailTo::EMAIL_REGEXP

Old TL;DR

VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i

Original answer

You seem to be complicating things a lot, I would simply use:

VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i

which is taken from michael hartl's rails book

since this doesn't meet your dot requirement it can simply be ammended like so:

VALID_EMAIL_REGEX = /\A([\w+\-]\.?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i

As mentioned by CAustin, there are many other solutions.

EDIT:

it was pointed out by @installero that the original fails for subdomains with hyphens in them, this version will work (not sure why the character class was missing digits and hyphens in the first place).

VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i

Email validation in Ruby on Rails?

I use the constant built into URI in the standard ruby library

validates :email, format: { with: URI::MailTo::EMAIL_REGEXP } 

What's the state of the art in email validation for Rails?

With Rails 3.0 you can use a email validation without regexp using the Mail gem.

Here is my implementation (packaged as a gem).

How can I validate multiple email addresses in a model?

You can use the TMail::Address module to validate an email as shown here. Custom validations can be added with the validate method.

validate :check_email_addresses

def check_email_addresses
email_addresses.split(/,\s*/).each do |email|
TMail::Address.parse(email)
end
rescue TMail::SyntaxError
errors.add(:email_addresses, "are not valid")
end

Update: The TMail::Address module seems to be too lax on what is considered a valid email address (see comments below) so instead you can use a regular expression.

validate :check_email_addresses

def check_email_addresses
email_addresses.split(/,\s*/).each do |email|
unless email =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
errors.add(:email_addresses, "are invalid due to #{email}")
end
end
end

There are a variety of regular expression solutions for validating an email address. See this page for details.

rails - REGEX for email validation

My shot at this (see comment and link above):

^.+@.+$

How to validate email is real or fake in Rails?

you can use ruby gem to handle for checking email is real or fake. Awesome, it support validate for model.

https://github.com/minhquan4080/email_detected

What's the best way to validate multiple emails and handle errors in Rails?

Assuming this is a model that has_many emails, and the email model uses :validate_email, you could do something like the following:

class Foo < ActiveRecord::Base
validate :must_not_have_invalid_addresses

...

def emails=(addresses)
@invalid_addresses = []
addresses.split(",").each do |address|
@invalid_addresses.push(address) unless emails.create({:address => address})
end
end

def must_not_have_invalid_addresses
errors.add_to_base("Some email addresses were invalid") unless @invalid_addresses.empty?
end

end

This provides a validation error + an array of the invalid email addresses which you can make accessible to your view if you like.

rails email validation format and regex

Let us break down the expression (keep in mind the i modifier makes it case insensitive):

\A          (?# anchor to the beginning of the string)
[\w+\-.]+ (?# match 1+ a-z, A-Z, 0-9, +, _, -, or .)
@ (?# match literal @)
[a-z\d\-.]+ (?# match 1+ a-z, 0-9, -, or .)
\. (?# match literal .)
[a-z]+ (?# match 1+ a-z)
\z (?# anchor to the absolute end of the string)

This is what the tutorial defines as an email (in reality, it's much more complicated). So the author, Michael Hartl, wrote a couple tests for "valid" and "invalid" (according to the above definitions) emails.

Pretty much the "user" can be alphanumeric or contain _+-.. The "domain" can be alphanumeric or -.. And the "TLD" can only be letters. The first 5 emails use many variations of these previous rules as "acceptable" emails. The last 5 emails fail for the following reasons:

  • user@example,com - , can't be matched
  • user_at_foo.org - no @
  • user.name@example. - no TLD after .
  • foo@bar_baz.com - domain can't contain _
  • foo@bar+baz.com - domain can't contain +

Obviously if you want more specific emails to match (or not match) add them to the array of tests. If your test fails, you know you will need to update your expression :)



Related Topics



Leave a reply



Submit