【问题标题】:How can I validate multiple email addresses in a model?如何验证模型中的多个电子邮件地址?
【发布时间】:2009-08-10 14:13:15
【问题描述】:

例如:逗号分隔在单个文本字段中:ma​​il1@domain.com、mail2@someotherdomain、...

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    您可以使用 TMail::Address 模块将电子邮件验证为shown here。可以使用validate 方法添加自定义验证。

    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
    

    更新: TMail::Address 模块似乎对有效的电子邮件地址过于宽松(请参阅下面的 cmets),因此您可以使用正则表达式。

    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
    

    有多种正则表达式解决方案可用于验证电子邮件地址。见this page for details

    【讨论】:

    • 真的有用吗? >> ret = TMail::Address.parse "invalid" => #<:address invalid>
    • 嗯,我猜在某些极端情况下可能是有效的电子邮件地址。但这对于验证表单中的电子邮件并没有太大帮助。我会更新答案...
    【解决方案2】:

    如果有人试图解析包含姓名的地址列表(可能出现在电子邮件标题中),我发现这样做的最简单方法是:

    header = TMail::HeaderField.new('to', address_list_string)
    

    header.addrs 将包含一组TMail::Address 对象,您可以访问这些对象的名称、电子邮件地址、域等。

    【讨论】:

    • 我喜欢使用 TMail 进行验证的可读性,但我很难让它在列表中工作。就我而言,TMail 似乎坚持使用逗号分隔的地址,所以我在传递给 TMail 之前用逗号替换换行符和分号:address_list_string.gsub(";",',').gsub("\n",',').gsub("\r",',') - 我在网站上运行后添加了 \r 替换。它很笨重,但很有效,而且我很容易理解它在做什么。
    【解决方案3】:

    我使用以下内容:

    
    module EmailValidator
      self.email_name_regex  = '[\w.%+-]+'.freeze
      self.domain_head_regex = '(?:[A-Z0-9-]+.)+'.freeze
      self.domain_tld_regex  = '(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|jobs|museum)'.freeze
      self.bracketed_email_regex = /\A.<\s(#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex})\s*>.\z/i
      self.unbracketed_email_regex = /\A\s(#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex})\s*\z/i
    
    

    def self.valid_email?(s) !(s =~ bracketed_email_regex || s =~unbracketed_email_regex).nil? end end

    那么你可以这样做:
    
    address_field.split(/\s*,\s*/).select {|addr| EmailValidator.valid_email?(addr)}
    

    【讨论】:

      【解决方案4】:

      查看 ActiveRecord::Validations::ClassMethods,特别是 validates_each 方法。

      http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M002161

      这将允许您将属性作为一个块传递,然后您可以编写自己的验证方法,该方法将拆分您的字符串并将每个电子邮件地址验证为正则表达式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-12
        • 1970-01-01
        • 2013-10-14
        • 2014-09-21
        • 1970-01-01
        • 2018-03-13
        相关资源
        最近更新 更多