выполнить одну проверку, только если все остальные проверки пройдены - PullRequest
28 голосов
/ 28 января 2011

Я создаю пользовательскую проверку, которая проверяет номер банковского счета и код сортировки с помощью внешнего API, чтобы проверить, существуют ли они (т.е. это правильный действительный банковский счет в Великобритании). Поскольку это дорогостоящая операция, я не хочу беспокоиться об использовании API, если только номер счета и код сортировки не проходят встроенную валидацию Rails.

Например, у меня есть следующие основные проверки:

validates_presence_of :sort_code, :account_number
validates_format_of :sort_code, :with => Regexes::SORT_CODE
validates_format_of :account_number, :with => Regexes::ACCOUNT_NUMBER

Тогда у меня есть пользовательская проверка:

validate :check_valid_bank_account

def check_valid_bank_account
  # code here is irrelevant, but essentially this hits the API
  # if it's a valid UK bank account all is OK, if not we add an error
end

Я хочу убедиться, что пользовательская проверка выполняется только в том случае, если остальная часть модели действительна. Нет смысла платить 25 пенсов за то, что мне сказали, что номер счета не был предоставлен, когда я смогу решить это сам!

Я знаю, что мог бы написать некоторую логику, которая проверяет, чтобы два атрибута не были пустыми, и сопоставляла их с регулярным выражением вручную ... но это не похоже на метод Rails.

Ответы [ 3 ]

32 голосов
/ 28 января 2011

Вы можете проверить массив errors и вернуть.

def check_valid_bank_account
  return unless errors.blank?
  …
end
8 голосов
/ 28 января 2011

Я бы действительно рекомендовал вывести этот код из метода проверки и поместить его в отдельный "valid_bank_account?" метод, который можно вызвать вручную, когда вы действительно хотите использовать API, особенно потому, что это дорогостоящая операция. Некоторые причины такого поведения заключаются в том, что вы можете не выполнять эту проверку, если номер учетной записи не изменился или вы только обновляете запись.

def save_only_with_valid_bank_account
  if @account.valid? && @account.valid_bank_number? && @account.save
   ...
  end
end

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

5 голосов
/ 18 июля 2012

используйте что-то вроде этого

validates_presence_of :sort_code, :account_number
validates_format_of :sort_code, :with => Regexes::SORT_CODE
validates_format_of :account_number, :with => Regexes::ACCOUNT_NUMBER
validate :check_valid_bank_account, :if => :should_i_call_custom_validation?

def should_i_call_custom_validation?
  # check for attributes or errors, errors.empty? should work
end

здесь тоже должен работать проц

validate :check_valid_bank_account, :if => Proc.new{|object| object.errors.empty?}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...