Skip to content

Instantly share code, notes, and snippets.

@stevenharman
Last active December 20, 2015 11:59
Show Gist options
  • Save stevenharman/6127973 to your computer and use it in GitHub Desktop.
Save stevenharman/6127973 to your computer and use it in GitHub Desktop.
A really robust (but still likely not full-spec compliant) email validator for ActiveModel.
# encoding: binary
require 'active_model/validator'
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment