2016-09-21 124 views
0

我有两个验证:避免重复验证器

validates :email, format: { with: /\A(.+)@(aol|gmail|office365|outlook|verizon|yahoo)\.com\Z/i }, if: Proc.new { |user| user.imap_server.blank? } 
validates :email, presence: true 
validates :imap_server, presence: true, if: Proc.new { |user| user.email.present? && user.email_invalid? } 


def email_invalid? 
    self.email =~ /\A(.+)@(aol|gmail|office365|outlook|verizon|yahoo)\.com\Z/i 
end 

我展示用户的形式。它显示一个email字段,但不显示imap_server字段。如果email字段中的值与特定的正则表达式不匹配,那么我想再次显示它们的形式,同时出现imap_server字段。如果他们输入imap_server字段的值,那么我不再需要验证email字段的正则表达式(尽管它仍然存在)。

感觉就像我复制验证的问题。 email_invalid?validates :email, format: ...都做同样的事情。我怎样才能清理它?

+2

至少您可以将正则表达式提取到本地常量并以此方式重用。 –

回答

1

你可以替换validates :email, format: ...

validate :email_format 

def email_format 
    errors.add(:email, 'format invalid') if imap_server.blank? && email_invalid? 
end 

稍微更行,但您可以在一个地方定义格式验证。

+0

从控制台尝试并发送无效的电子邮件时,这绝不会检测到“format invalid”消息。 – Donato

+0

你在做'my_record.valid?'对吗? – SteveTurczyn

+0

是的,即使我使用“[email protected]”的电子邮件,它也会返回true。然而,我在问题中的原始方式,它返回false。 – Donato

0

我怀疑问题在于你正在尝试检查验证结果(email_invalid?),而你仍在执行验证......你不知道验证的顺序是什么(页面上的订单不是我信赖的东西)...所以解决它的最好方法是将所有这些东西写入单个验证方法,例如快速和肮脏的方法:

validates :email_or_imap_server 

def email_or_imap_server 
    email_valid = false # for scoping 
    if email.present? 
    # note: email validation via regex is harder than you think... 
    # google it... 
    email_valid = email.match(/#{VALID_EMAIL_FORMATS}/) 
    if email_invalid 
     errors.add(:email, "email invalid format should be...") 
     errors.add(:imap_server, "email or imap-server must be present") unless imap_server.present? 
    end 
    else 
    errors.add(:imap_server, "either email or imap-server must be present") unless imap_server.present? 
    end 
end 

注:上面的代码几乎可以肯定充满错误和错别字......不要复制/粘贴它几乎肯定将无法正常工作和逻辑并不完全匹配您v alidations ...但做这样的事情。