Class: Axn::Validators::OfValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Defined in:
lib/axn/core/validation/validators/of_validator.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.apply_syntactic_sugar(value, _fields) ⇒ Object



8
9
10
11
12
# File 'lib/axn/core/validation/validators/of_validator.rb', line 8

def self.apply_syntactic_sugar(value, _fields)
  return value if value.is_a?(Hash)

  { klass: value }
end

Instance Method Details

#check_validity!Object

Raises:

  • (ArgumentError)


14
15
16
# File 'lib/axn/core/validation/validators/of_validator.rb', line 14

def check_validity!
  raise ArgumentError, "must supply :klass" if options[:klass].nil?
end

#validate_each(record, attribute, value) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/axn/core/validation/validators/of_validator.rb', line 18

def validate_each(record, attribute, value)
  return if value.nil? && (options[:allow_nil] || options[:allow_blank])
  return unless value.is_a?(Array) # TypeValidator owns the non-Array error

  klasses = Array(options[:klass])
  # A custom message: replaces the type description but the index is always reported —
  # element position is the locating info that makes a per-element error actionable.
  msg = options[:message] || (klasses.size == 1 ? "is not a #{klasses.first}" : "is not one of #{klasses.join(', ')}")

  value.each_with_index do |el, i|
    # allow_blank governs whether the whole field may be absent (handled above), not whether
    # individual elements may be blank — so it is intentionally not passed to the matcher.
    valid = klasses.any? { |k| TypeValidator.value_matches?(el, klass: k) }
    record.errors.add(attribute, "element at index #{i} #{msg}") unless valid
  end
end