I wrote this short, plain Ruby lib to handle email address validation inside and outside of Rails applications, and I would like to know what you think.
require "i18n"
class EmailAddress
VALID_EMAIL_ADDRESS_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
def self.malformed?(email)
email !~ VALID_EMAIL_ADDRESS_REGEX
end
def self.valid?(email)
!malformed?(email)
end
attr_reader :email, :i18n_scope, :errors
def initialize(email, i18n_scope: [:models, :email_address])
@email = email
@i18n_scope = i18n_scope
@errors = []
end
def valid?
validate
errors.empty?
end
def validate
message = I18n.t(:invalid, scope: i18n_scope)
errors.push(message) if EmailAddress.malformed?(email)
end
end
Usage can be as simple as:
if EmailAddress.valid?(params[:email))
# do something
end
Or for remote validations, for example:
def email
email = EmailAddress.new(params[:email])
if email.valid?
render nothing: true, status: 200
else
render json: { errors: email.errors }, status: 422
end
end
1 Answer 1
The Regex will validate some email addresses. Because the Domain Name System allows UniCode. the Regex does not match all valid characters in the Doman Name. Therefore it will not validate all valid email addresses.
Alternatives:
Validating over all allowable Unicode with Regex in a meaningful way is non-trivial.
Sending a confirmation email requiring reply is a straight-forward method for validating email procedurally.
When possible, not collecting email addresses at all is easy to implement.
isemail.info/#{emailaddress}
. Unfortunately it doesn't appear that he has a ruby gem for it, so if you have an internet connection then that should be your first choice. \$\endgroup\$