Проверить наличие поля только в том случае, если другое поле пуст - 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.
Ответы
Ответ 1
Вам не нужна лямбда. Это будет делать:
validates_presence_of :mobile_number, :unless => :home_phone?
Кроме того, все валидаторы принимают одинаковые параметры if/except, поэтому вы можете сделать их условными по своему усмотрению.
Обновление. Оглядываясь назад на этот ответ несколько дней спустя, я вижу, что я должен объяснить, почему он работает:
- Если вы установите параметр validator
:unless
как символ, Rails будет искать метод экземпляра этого имени, вызывать этот метод в проверяемом экземпляре - во время проверки - и выполнять только проверку, если метод возвращает false.
- ActiveRecord автоматически создает методы вопросительных меток для каждого из ваших атрибутов модели, поэтому наличие столбца
home_phone
в вашей таблице моделей заставляет Rails создавать удобный метод #home_phone?
. Этот метод возвращает true тогда и только тогда, когда присутствует home_phone (т.е. Не пусто). Если атрибут home_phone равен нулю или пустой строке или пучке пробелов, home_phone? вернет false.
UPDATE: подтверждено, что эта старая техника продолжает работать в Rails 5.
Ответ 2
Вы должны использовать объект lambda
/Proc
:
validates_presence_of :mobile_number, :unless => lambda { self.home_phone.blank? }
Ответ 3
Вот еще один способ, который работает в рельсах 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 }
Ответ 4
короткое решение:
validates_presence_of :mobile_number, unless: -> { home_phone.blank? }
Ответ 5
Начиная с Rails 4, вы можете передать блок на наличие. Лаконично:
validates :mobile_number, presence: {unless: :home_phone?}
Кроме того, :home_phone?
возвращает false для nil или blank.