仅当另一个字段为空时才验证字段的存在 - Rails

时间:2011-06-08 01:21:02

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

我有一张带有手机/手机号码和家庭电话号码的表格。

如果电话号码留空,我想只验证手机/手机号码的存在,反之亦然。

我对这些字段的当前验证如下。

validates_presence_of :mobile_number
validates_presence_of :home_phone

validates_length_of :home_phone, :minimum => 12, :maximum => 12
validates_length_of :mobile_number, :minimum => 10, :maximum => 10, :allow_blank => true

validates_format_of :home_phone, :with => /\A[0-9]{2}\s[0-9]{4}\s[0-9]{4}/, :message => "format should be 02 9999 9999"

我以为我可以拥有以下内容,但不确定如何做到这一点。

validates_presence_of :mobile_number, :unless => :home_phone.blank?

我正在使用Rails 3。

5 个答案:

答案 0 :(得分:115)

你不需要lambda。这样做:

validates_presence_of :mobile_number, :unless => :home_phone?

此外,所有验证器都使用相同的if / unless选项,因此您可以随意使它们成为条件。

更新:几天后回顾这个答案,我看到我应该解释它为何有效:

  • 如果您将验证程序的:unless选项设置为符号,则Rails将查找该名称的实例方法,在验证时调用正在验证的实例上的该方法,并仅执行验证方法是否返回false。
  • ActiveRecord会自动为每个模型的属性创建问号方法,因此模型表中存在home_phone列会导致Rails创建方便的#home_phone?方法。当且仅当home_phone存在时(即非空白),此方法返回true。如果home_phone属性为nil或空字符串或一堆空格,home_phone?将返回false。

更新:确认这项旧技术在Rails 5中继续有效。

答案 1 :(得分:22)

您必须使用lambda / Proc对象:

validates_presence_of :mobile_number, :unless => lambda { self.home_phone.blank? }

答案 2 :(得分:7)

从Rails 4开始,您可以将块传递给状态。简明地:

validates :mobile_number, presence: {unless: :home_phone?}

此外,:home_phone?对于nil或空白返回false。

答案 3 :(得分:2)

这是另一种适用于rails 4的方法

  validates_presence_of :job, if: :executed_at?

  validates :code,
            presence: true,
            length:  { minimum: 10, maximum: 50 },
            uniqueness: { case_sensitive: false },
            numericality: { only_integer: true }

答案 4 :(得分:0)

一个简短的解决方案:

validates_presence_of :mobile_number, unless: -> { home_phone.blank? }