Class: Axn::Validators::ShapeValidator
- Inherits:
-
ActiveModel::EachValidator
- Object
- ActiveModel::EachValidator
- Axn::Validators::ShapeValidator
- Defined in:
- lib/axn/core/validation/validators/shape_validator.rb
Overview
Validates the per-member shape of a structured field declared via a block:
expects :items, type: Array do
field :status, type: String, inclusion: { in: %w[a b] }
end
options is an array of ShapeConfig-like objects (responding to #field and
#validations, and optionally #method_call/#user_facing — a member that doesn't implement one
defaults to not opted in); options is the declared structured type (Array, Hash, or a class).
A shape DECLARED through expects/exposes always supplies axn's own ShapeConfig, so the duck-typing
here serves exactly one route: a field config ASSIGNED onto a class (internal_field_configs=), which
carries the caller's own member objects because it passed no declaration walk. This validator is
deliberately not registered globally (see Validation::Base), so a consuming app's own validates cannot
reach it and is not a route.
For an Array container each element is validated with its index in the message; for any other
container the single value's members are validated directly. A value that doesn't match the
declared container is left to TypeValidator (we don't try to extract members from it). Nesting
falls out for free: a member whose validations include a :shape key recurses through the same
machinery.
Instance Method Summary collapse
Instance Method Details
#check_validity! ⇒ Object
28 29 30 |
# File 'lib/axn/core/validation/validators/shape_validator.rb', line 28 def check_validity! raise ArgumentError, "must supply :members" if [:members].nil? end |
#validate_each(record, attribute, value) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/axn/core/validation/validators/shape_validator.rb', line 32 def validate_each(record, attribute, value) return if value.nil? && ([:allow_nil] || [:allow_blank]) if [:container] == Array return unless value.is_a?(Array) # TypeValidator owns the non-Array error value.each_with_index do |element, index| validate_members(record, attribute, element, prefix: "element at index #{index}: ") end else return unless value.is_a?([:container]) # TypeValidator owns the type mismatch validate_members(record, attribute, value, prefix: "") end end |