Я сделал что-то подобное. Я просто использую модуль валидации здесь, но он применяется к активным моделям записей таким же образом. Существует множество различных модификаций, которые можно сделать, но это почти та же самая реализация, которую я использовал.
- Необходимо перечислить проверки в порядке
- Может быть изменено, чтобы остановить любую ошибку, включая instance.errors [: base]
- Можно ли остановить любую ошибку, используя instance.errors.any?
- Метод with_options будет фактически передавать «yes: Proc» каждой проверке, поэтому он на самом деле
- выполняется для каждой проверки
- with_options можно заменить, просто указав условия if или else для каждой проверки
Определение класса. Версия без AR. То же самое можно сделать с ActiveRecord :: Базовые классы
class Skippy
# wouldnt need to do this initialize on the ActiveRecord::Base model version
include ActiveModel::Validations
validate :first
validate :second
validate :halt_on_third
validates_presence_of :or_halt_on_fourth
with_options unless: Proc.new{ |instance| [:halt_on_thirds_error_key, :or_halt_on_fourth].any?{ |key| instance.errors[key].any? } } do |instance|
instance.validate :wont_run_fifth
instance.validates_presence_of :and_wont_run_sixth
end
# wouldn't need to do these on the ActiveRecord::Base model version
attr_accessor :attributes
def initialize
@attributes = { or_halt_on_fourth: "I'm here" }
end
def read_attribute_for_validation(key)
@attributes[key]
end
def first
errors.add :base, 'Base error from first'
end
def second
errors.add :second, 'Just an error'
end
def halt_on_third
errors.add :halt_on_thirds_error_key, 'Halting error' unless @donthalt
end
def wont_run_fifth
errors.add :wont_run_fifth, 'ran because there were no halting errors'
end
end
Демо
2.0.0 :040 > skippy = Skippy.new
=> #<Skippy:0x0000000d98c1c0 @attributes={:or_halt_on_fourth=>"I'm here"}>
2.0.0 :041 > skippy.errors.any?
=> false
2.0.0 :042 > skippy.valid?
=> false
2.0.0 :043 > skippy.errors.full_messages
=> ["Base error from first", "Second Just an error", "Halt on thirds error key Halting error"]
2.0.0 :044 > skippy.errors.clear
=> {}
2.0.0 :045 > skippy.instance_variable_set(:@donthalt, true)
=> true
2.0.0 :046 > skippy.errors.any?
=> false
2.0.0 :047 > skippy.valid?
=> false
2.0.0 :048 > skippy.errors.full_messages
=> ["Base error from first", "Second Just an error", "Wont run fifth ran because there were no halting errors", "And wont run sixth can't be blank"]
2.0.0 :049 > skippy.errors.clear; skippy.attributes = {}; skippy.errors.any?
=> false
2.0.0 :050 > skippy.valid?; skippy.errors.full_messages
=> ["Base error from first", "Second Just an error", "Or halt on fourth can't be blank"]
2.0.0 :051 >