Skip to content

class Athena::Validator::Constraints::Sequentially
inherits Athena::Validator::Constraints::Composite #

Validates a value against a collection of constraints, stopping once the first violation is raised.


Required Arguments#


Type: Array(AVD::Constraint) | AVD::Constraint

The AVD::Constraint(s) that are to be applied sequentially.

Optional Arguments#


This constraint does not support a message argument.


Type: Array(String) | String | Nil Default: nil

The validation groups this constraint belongs to. AVD::Constraint::DEFAULT_GROUP is assumed if nil.


Type: Hash(String, String)? Default: nil

Any arbitrary domain-specific data that should be stored with this constraint. The payload is not used by Athena::Validator, but its processing is completely up to you.


Suppose you have an object with a address property which should meet the following criteria:

  • Is not a blank string
  • Is at least 10 characters long
  • Is in a specific format
  • Is geolocalizable using an external API

If you were to apply all of these constraints to the address property, you may run into some problems. For example, multiple violations may be added for the same property, or you may perform a useless and heavy external call to geolocalize the address when it is not in a proper format.

To solve this we can validate these constraints sequentially.

class Location
  include AVD::Validatable

  PATTERN = /some_pattern/

  def initialize(@address : String); end

  getter address : String


The annotation approach only supports two levels of nested annotations. Manually wire up the constraint via code if you require more than that.

Class methods#

.new(constraints : Array(AVD::Constraint) | AVD::Constraint, groups : Array(String) | String | Nil = nil, payload : Hash(String, String)? = nil) #

View source


#validated_by : AVD::ConstraintValidator.class #

Returns the AVD::ConstraintValidator.class that should handle validating self.

View source