我有一个表格,上面有手机/手机号码和家庭电话号码。
如果电话号码留空,我只想验证手机/手机号码的存在,反之亦然。
我目前对这些字段的验证如下。
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?
此外,所有验证器都采用相同的 if/except 选项,因此您可以随意使它们成为条件。
更新:几天后回头看这个答案,我发现我应该解释为什么它有效:
- 如果将验证器的
:unless
选项设置为符号,Rails 将查找该名称的实例方法,在验证时在正在验证的实例上调用该方法,并且仅在该方法返回 false 时才执行验证。 - ActiveRecord 会自动为模型的每个属性创建问号方法,因此模型表中存在
home_phone
列会导致 Rails 创建一个方便的#home_phone?
方法。此方法返回 true 当且仅当home_phone存在(即不为空(。如果 home_phone 属性为 nil 或空字符串或一堆空格,home_phone?将返回假。
更新:确认这种旧技术在 Rails 5 中继续有效。
必须使用 lambda
/Proc
对象:
validates_presence_of :mobile_number, :unless => lambda { self.home_phone.blank? }
从 Rails 4 开始,你可以将块传递给 Presence。总之:
validates :mobile_number, presence: {unless: :home_phone?}
此外,对于 nil 或空白,:home_phone?
返回 false。
在 Rails 7 中测试,这完美无缺:
validates :mobile_number, presence: { unless: :home_phone }
这是在 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 }
一个简短的解决方案:
validates_presence_of :mobile_number, unless: -> { home_phone.blank? }
在较新版本的 Rails 中,与其依赖旧validates_presence_of
,不如对每个属性使用validates
和列表验证:
validates :mobile_number, presence: { if: -> { home_phone.present? } }