Как обрабатывать зависимые проверки на Rails? - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть некоторые проверки Active Record на моей модели:

class Product < ApplicationRecord
  validates :name, presence: true, length: { is: 10 }
end

Кажется, все в порядке. Он подтверждает, что поле name не является nil, "" и что оно должно содержать ровно 10 символов. Теперь, если я хочу добавить пользовательскую проверку , я бы добавил вызов validate:

class Product < ApplicationRecord
  validates :name, presence: true, length: { is: 10 }
  validate :name_must_start_with_abc

  private

  def name_must_start_with_abc
    unless name.start_with?('abc')
      self.errors['name'] << 'must start with "abc"'
    end
  end
end

Проблема в том, что когда поле name равно nil, проверка presence_of его перехватит, но не помешает проверке с помощью пользовательского метода name_must_start_with_abc, подняв NoMethodError, как name равно nil.

Чтобы преодолеть это, я должен добавить ноль-проверку к методу name_must_start_with_abc.

def name_must_start_with_abc
  return if name.nil?

  unless name.start_with?('abc')
    self.errors['name'] << 'must start with "abc"'
  end
end

Это то, чего я не хочу делать, потому что, если я добавлю больше «зависимых» проверок, мне придется повторно проверять их для каждого пользовательского метода проверки.

Как обрабатывать зависимые проверки на Rails? Есть ли способ предотвратить вызов пользовательской проверки, если другие проверки не прошли?

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Я думаю, что нет идеального решения, если вы не напишите все свои проверки в качестве пользовательских методов. Подход, который я часто использую:

class Product < ApplicationRecord
  validates :name, presence: true, length: { is: 10 }
  validate :name_custom_validator

  private

  def name_custom_validator
    return if errors.include?(:name)

    # validation code
  end
end

Таким образом, вы можете добавить столько проверок к :name, и если любая из них завершится неудачно, ваш пользовательский валидатор не будет выполнен. Но проблема с этим кодом в том, что ваш пользовательский метод проверки должен быть последним.

0 голосов
/ 06 ноября 2018
class Product < ApplicationRecord
  validates :name, presence: true, length: { is: 10 }
  validate :name_must_start_with_abc, unless: Proc.new { name.nil? }

  private

  def name_must_start_with_abc
    unless name.start_with?('abc')
      self.errors['name'] << 'must start with "abc"'
    end
  end
end

Пожалуйста, проверьте allow_blank , : allow_nil и условная проверка , а также дополнительные параметры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...