ROR如何在自定义验证中最好地处理nil

时间:2012-05-28 16:29:48

标签: ruby ruby-on-rails-3 ruby-on-rails-3.2

我有这个自定义验证,抛出“未定义的方法`>”为nil:NilClass“因为生日没有设定,因为生日是零。

validate :is_21_or_older 
def is_21_or_older
  if birthday > 21.years.ago.to_date
    errors.add(:birthday, "Must 21 Or Older")
  end
end

我已经有了validates_presence_of的生日,所以有没有办法在validates_presence_of通过后调用is_21_or_older?

1 个答案:

答案 0 :(得分:3)

Rails独立运行所有验证器,以便一次性为您提供所有错误的数组。这样做是为了避免过于常见的情况:

  

请输入密码。

     

<强> pass

     

您输入的密码无效:它不包含数字。

     

<强> 1234

     

您输入的密码无效:它不包含字母。

     

<强> a1234

     

您输入的密码无效:长度不超过六个字符。

     

<强> ab1234

     

您输入的密码无效:您不能在序列中使用三个或更多连续字符。

     

<强> piss off

     

您输入的密码无效:它不包含数字。

我知道有两件事你可以做。要么包含自定义验证程序下的所有内容,在这种情况下,一切都在您的控制之下,或者使用:unless => Proc.new { |x| x.birthday.nil? }修饰符明确限制验证程序在其中断的情况下运行。我肯定建议第一种方法;第二个是hacky。

def is_21_or_older
  if birthday.blank?
    errors.add(:birthday, "Must have birthday")
  elsif birthday > 21.years.ago.to_date
    errors.add(:birthday, "Must 21 Or Older")
  end
end

也许更好的方法是保留在线验证器,只要在看到其他验证器的条件失败时退出自定义验证器。

def is_21_or_older
  return true if birthday.blank? # let the other validator handle it

  if birthday > 21.years.ago.to_date
    errors.add(:birthday, "Must 21 Or Older")
  end
end