Подтвердить что ты не робот

Выполнить одну проверку только в том случае, если все остальные проверки пройдут

Я создаю специальную проверку, которая проверяет номер банковского счета и код сортировки с внешним 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 a valid UK bank account all is OK, if not we add an error
end

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

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

4b9b3361

Ответ 1

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

def check_valid_bank_account
  return unless errors.blank?
  …
end

Ответ 2

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

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

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

Ответ 3

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

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

также должен работать и Proc

validate :check_valid_bank_account, :if => Proc.new{|object| object.errors.empty?}