仅当另一个字段为空时validation字段的存在 – Rails

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

如果电话号码留空,我只希望validation是否存在手机/手机号码,反之亦然。

我目前对这些领域的validation如下。

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。

你不需要lambda。 这将做到:

 validates_presence_of :mobile_number, :unless => :home_phone? 

另外,所有的validation器都采用相同的/如果/除非选项,所以你可以使它们有条件的任意。

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

  • 如果你设置了一个validation器:unless选项是一个符号, :unless Rails将查找该名称的一个实例方法,在validation的时候对正在validation的实例调用该方法 – 只在方法返回false时才执行validation。
  • ActiveRecord会自动为你的模型的每个属性创build问号方法,所以你的模型表中存在一个home_phone列会导致Rails创build一个方便的#home_phone? 方法。 当且仅当home_phone存在时(即不是空白),此方法返回true。 如果home_phone属性是零或空string或一堆空白,home_phone? 将返回false。

更新:确认这个旧技术继续在Rails 5中工作。

您必须使用lambda / Proc对象:

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

这是另一种在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 } 

简短的解决scheme:

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

从Rails 4开始,你可以传递一个块到状态。 简明:

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

另外, :home_phone? 对于零或空白返回false。