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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6273289/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 01:20:48  来源:igfitidea点击:

Validate presence of field only if another field is blank - Rails

ruby-on-railsruby-on-rails-3

提问by Robert B

I have a form with a mobile/cell number and a home phone number.

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

I want to have only validate presence of mobile/cell number if the phone number has been left blank or vice versa.

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

My current validations for these fields are as follows.

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

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"

I thought I could have something like the following but not sure how to do this exactly.

我以为我可以有类似以下的东西,但不确定如何准确地做到这一点。

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

I'm using Rails 3.

我正在使用 Rails 3。

回答by Rob Davis

You don't need a lambda. This will do:

您不需要 lambda。这将:

validates_presence_of :mobile_number, :unless => :home_phone?

Also, all of the validators take the same if/unless options, so you can make them conditional at will.

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

Update:Looking back at this answer a few days later, I see that I should explain why it works:

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

  • If you set a validator's :unlessoption to be a symbol, Rails will look for an instance method of that name, invoke that method on the instance that's being validated -- at validation time -- and only perform the validation if the method returns false.
  • ActiveRecord automatically creates question mark methods for each of your model's attributes, so the existence of a home_phonecolumn in your model's table causes Rails to create a handy #home_phone?method. This method returns true if and only if home_phone is present (i.e. not blank). If the home_phone attribute is nil or an empty string or a bunch of white space, home_phone? will return false.
  • 如果您将验证器的:unless选项设置为符号,Rails 将查找该名称的实例方法,在正在验证的实例上调用该方法——在验证时——并且只有在方法返回 false 时才执行验证。
  • ActiveRecord 会自动为模型的每个属性创建问号方法,因此home_phone模型表中列的存在会导致 Rails 创建一个方便的#home_phone?方法。当且仅当 home_phone 存在(即不为空)时,此方法返回 true。如果 home_phone 属性为 nil 或空字符串或一堆空格,home_phone?将返回假。


UPDATE: Confirmed that this old technique continues to work in Rails 5.

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

回答by Ryan Bigg

You must use a lambda/ Procobject:

您必须使用lambda/Proc对象:

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

回答by IAmNaN

Starting in Rails 4, you can pass a block to presence. Concisely:

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

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

Also, :home_phone?returns false for nil or blank.

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

回答by Chris Hough

Here is another way that works in rails 4

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

回答by John

a short solution:

一个简短的解决方案:

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