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

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

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

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

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。

Robert B asked 2019-11-12T16:28:56Z
5个解决方案
120 votes

您不需要lambda。 这样可以:

validates_presence_of :mobile_number, :unless => :home_phone?

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

更新:几天后回头看这个答案,我发现我应该解释它为什么起作用:

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

更新:确认此旧技术可继续在Rails 5中使用。

Rob Davis answered 2019-11-12T16:30:01Z
23 votes

您必须使用lambda/Proc对象:

validates_presence_of :mobile_number, :unless => lambda { self.home_phone.blank? }
Ryan Bigg answered 2019-11-12T16:30:27Z
7 votes

从Rails 4开始,您可以将一个块传递给状态。 简而言之:

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

此外,:home_phone?会返回false表示nil或空白。

IAmNaN answered 2019-11-12T16:31:03Z
2 votes

这是在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 }
Chris Hough answered 2019-11-12T16:31:34Z
0 votes

一个简短的解决方案:

validates_presence_of :mobile_number, unless: -> { home_phone.blank? }
John answered 2019-11-12T16:32:09Z
translate from https://stackoverflow.com:/questions/6273289/validate-presence-of-field-only-if-another-field-is-blank-rails