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

Rob*_*t B 54 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"
Run Code Online (Sandbox Code Playgroud)

我以为我可以有类似下面这样的东西,但不知道如何完全这样做.

validates_presence_of :mobile_number, :unless => :home_phone.blank?
Run Code Online (Sandbox Code Playgroud)

我正在使用Rails 3.

Rob*_*vis 121

你不需要lambda.这样做:

validates_presence_of :mobile_number, :unless => :home_phone?
Run Code Online (Sandbox Code Playgroud)

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

更新:几天后回顾这个答案,我看到我应该解释它的工作原理:

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

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

  • 我很感激您正在努力提供帮助.我只是说:不要编辑一个以"你不需要lambda"开头的答案,坚持使用lambda.这是荒谬的,而不是我写的.另一个答案是使用lambda,欢迎你投票支持我,或者提出相反的意见.这个答案对我来说很有用,所以我不确定为什么它在你的情况下不起作用. (3认同)

Rya*_*igg 23

您必须使用lambda/ Procobject:

validates_presence_of :mobile_number, :unless => lambda { self.home_phone.blank? }
Run Code Online (Sandbox Code Playgroud)

  • lambda在这里对我很有用,遗憾的是另一种方法失败了...... (2认同)

IAm*_*NaN 7

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

validates :mobile_number, presence: {unless: :home_phone?}
Run Code Online (Sandbox Code Playgroud)

此外,:home_phone?返回false为nil或空白.


drj*_*nco 6

在 Rails 7 中进行测试,效果完美:

validates :mobile_number, presence: { unless: :home_phone }
Run Code Online (Sandbox Code Playgroud)