避免在Rails验证器中重复

时间:2016-09-21 20:42:34

标签: ruby-on-rails

我有两个验证:

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 个答案:

答案 0 :(得分:1)

您可以将validates :email, format: ...替换为

validate :email_format

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

稍微多一行,但允许您在一个地方定义格式验证。

答案 1 :(得分: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

注意:上面的代码几乎肯定充满了错误和拼写错误...不要复制/粘贴它几乎肯定不会工作,并且逻辑与验证的逻辑不完全匹配......但是做这样的事情。