Ответ 1
Вы можете проверить массив errors
и вернуться.
def check_valid_bank_account
return unless errors.blank?
…
end
Я создаю специальную проверку, которая проверяет номер банковского счета и код сортировки с внешним 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-путь.
Вы можете проверить массив errors
и вернуться.
def check_valid_bank_account
return unless errors.blank?
…
end
Я бы рекомендовал извлечь этот код из метода проверки и поместить его в отдельный "valid_bank_account?". метод, который можно вызвать вручную, когда вы действительно хотите попасть в API, особенно потому, что это дорогостоящая операция. Некоторые причины такого поведения состоят в том, что вы не захотите выполнить эту проверку, если номер учетной записи не изменился или если вы только обновляете запись.
def save_only_with_valid_bank_account if @account.valid? && @account.valid_bank_number? && @account.save ... end end
Это более утомительно, но это гарантирует, что вы имеете контроль над тем, когда на самом деле происходит проверка.
используйте что-то вроде этого
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?}