Class: Axn::Validators::NonEmptinessValidator
- Inherits:
-
ActiveModel::EachValidator
- Object
- ActiveModel::EachValidator
- Axn::Validators::NonEmptinessValidator
- Defined in:
- lib/axn/core/validation/validators/non_emptiness_validator.rb
Overview
The check allow_empty: false installs when nothing else in the declaration already forbids an empty
value. It asks the value itself — empty? — which is the question the flag is about: a whitespace-only
String is blank but not empty, and so admissible, while an empty collection is rejected however its
size reads.
ActiveModel's length: { minimum: 1 } cannot ask it. LengthValidator measures
value.respond_to?(:length) ? value.length : value.to_s.length (activemodel 7.2.2.2), so a value that
reports no size is measured by its rendering: an empty ActionController::Parameters renders as "{}"
and clears a floor of 1 — while the emitted schema, which reads the declared floor, says
minProperties: 1.
A value that does not answer empty? splits in two, and the declared klasses the entry carries are what
tell them apart. A value the declared type does NOT match is simply the wrong type: its single error
belongs to TypeValidator, and this check stands aside rather than reporting the same defect twice. A
value the type DOES match cannot be judged at all — the declaration guard proved the TYPE has an empty
state (Contract _emptiable_type?), not that every instance keeps the method — so the contract is
unverifiable, and saying so is the only honest outcome: silently accepting would let an explicit
allow_empty: false go unenforced.
Constant Summary collapse
- CAPABILITY_CHECK =
Whether the value HAS a public
empty?, asked throughObject's own implementation bound to the value. A caller'srespond_to?is the caller's to define — a proxy or delegator routinely answers for methods it forwards, and one that answersfalseforempty?would otherwise disable a contract the declaration made — so the capability is asked of the object, not of its answer about itself.This is the same question the declaration guard asks of the declared type (
Contract._emptiable_type?), in the one form that is both unforgeable and total: asking the value's CLASS misses anempty?the value carries on its singleton (a value thatextends the declared module) and raises on aBasicObject, and asking itssingleton_classraises a TypeError for a frozen or immediate value. A hardening that raises on a weird-but-legal value would be worse than the hole it closes. ::Object.instance_method(:respond_to?)
Instance Method Summary collapse
-
#validate_each(record, attribute, value) ⇒ Object
EachValidator applies allow_nil:/allow_blank: before this runs, so the entry's nil-tolerance has already skipped a nil (the nil axis is
optional:/allow_nil:and the type check's business).
Instance Method Details
#validate_each(record, attribute, value) ⇒ Object
EachValidator applies allow_nil:/allow_blank: before this runs, so the entry's nil-tolerance has
already skipped a nil (the nil axis is optional:/allow_nil: and the type check's business).
42 43 44 45 46 47 48 49 |
# File 'lib/axn/core/validation/validators/non_emptiness_validator.rb', line 42 def validate_each(record, attribute, value) unless CAPABILITY_CHECK.bind_call(value, :empty?) record.errors.add(attribute, "cannot be checked for emptiness: it has no empty? method") if unanswerable?(value) return end record.errors.add(attribute, [:message] || "can't be empty") if value.empty? end |