class Athena::Validator::Constraints::Callback
Overview
Allows creating totally custom validation rules, assigning any violations to specific fields on your object. This process is achieved via using one or more callback methods which will be invoked during the validation process.
NOTE The callback method itself does fail or return any value.
Instead it should directly add violations to the AVD::ExecutionContextInterface
argument.
Configuration
Required Arguments
callback
Type: AVD::Constraints::Callback::CallbackProc?
Default: nil
The proc that should be invoked as the callback for this constraint.
NOTE If this argument is not supplied, the callback_name argument must be.
callback_name
Type: String?
Default: nil
The name of the method that should be invoked as the callback for this constraint.
NOTE If this argument is not supplied, the callback argument must be.
Optional Arguments
NOTE This constraint does not support a message
argument.
groups
Type: Array(String) | String | Nil
Default: nil
The [validation groups][Athena::Validator::Constraint--validation-groups] this constraint belongs to.
AVD::Constraint::DEFAULT_GROUP
is assumed if nil
.
payload
Type: Hash(String, String)?
Default: nil
Any arbitrary domain-specific data that should be stored with this constraint.
The [payload][Athena::Validator::Constraint--payload] is not used by Athena::Validator
, but its processing is completely up to you.
Usage
The callback constraint supports two callback methods when validating objects, and one callback method when using the constraint directly.
Instance Methods
To define an instance callback method, apply the @[Assert::Callback]
method to a public instance method defined within an object.
This method should accept two arguments: the AVD::ExecutionContextInterface
to which violations should be added,
and the AVD::Constraint@payload
from the related constraint.
More than one callback method can exist on a type, and the method name does not have to be validate
.
class Example
include AVD::Validatable
SPAM_DOMAINS = ["fake.com", "spam.net"]
def initialize(@domain_name : String); end
@[Assert::Callback]
def validate(context : AVD::ExecutionContextInterface, payload : Hash(String, String)?) : Nil
# Validate that the `domain_name` is not spammy.
return unless SPAM_DOMAINS.includes? @domain_name
context
.build_violation("This domain name is not legit!")
.at_path("domain_name")
.add
end
end
Class Methods
The callback method can also be defined as a class method. Since class methods do not have access to the related object instance, it is passed in as an argument.
That argument is typed as AVD::Constraints::Callback::Value
instance which exposes a AVD::Constraints::Callback::Value#get
method that can be used as an easier syntax than .as
.
class Example
include AVD::Validatable
SPAM_DOMAINS = ["fake.com", "spam.net"]
@[Assert::Callback]
def self.validate(value : AVD::Constraints::Callback::ValueContainer, context : AVD::ExecutionContextInterface, payload : Hash(String, String)?) : Nil
# Get the object from the value, typed as our `Example` class.
object = value.get self
# Validate that the `domain_name` is not spammy.
return unless SPAM_DOMAINS.includes? object.domain_name
context
.build_violation("This domain name is not legit!")
.at_path("domain_name")
.add
end
def initialize(@domain_name : String); end
getter domain_name : String
end
Procs/Blocks
When working with constraints in a non object context, a callback passed in as a proc/block.
AVD::Constraints::Callback::CallbackProc
alias can be used to more easily create a callback proc.
AVD::Constraints::Callback.with_callback
can be used to create a callback constraint, using the block as the callback proc.
See the related types for more information.
Proc/block based callbacks operate similarly to Class Methods in that they receive the value as an argument.
Defined in:
constraints/callback.crConstructors
Class Method Summary
-
.with_callback(**args, &block : AVD::Constraints::Callback::ValueContainer, AVD::ExecutionContextInterface, Hash(String, String) | Nil -> ) : AVD::Constraints::Callback
Convenience method for creating a
AVD::Constraints::Callback
with the given &block as the callback.
Instance Method Summary
-
#callback : AVD::Constraints::Callback::CallbackProc | Nil
Returns the proc that this constraint should invoke.
-
#callback_name : String | Nil
Returns the name of the callback method this constraint should invoke.
-
#validated_by : AVD::ConstraintValidator.class
Returns the
AVD::ConstraintValidator.class
that should handle validatingself
.
Instance methods inherited from class Athena::Validator::Constraint
add_implicit_group(group : String) : Nil
add_implicit_group,
groups : Array(String)
groups,
groups=(groups : Array(String))
groups=,
message : String
message,
payload : Hash(String, String) | Nil
payload,
validated_by : AVD::ConstraintValidator.class
validated_by
Constructor methods inherited from class Athena::Validator::Constraint
new(message : String, groups : Array(String) | String | Nil = nil, payload : Hash(String, String) | Nil = nil)
new
Class methods inherited from class Athena::Validator::Constraint
error_name(error_code : String) : String
error_name
Constructor Detail
Class Method Detail
Convenience method for creating a AVD::Constraints::Callback
with
the given &block as the callback.
# Instantiate a callback constraint, using the block as the callback
constraint = AVD::Constraints::Callback.with_callback do |value, context, payload|
next if (value = value.get(Int32)).even?
context.add_violation "This value should be even."
end
Instance Method Detail
Returns the proc that this constraint should invoke.
Returns the name of the callback method this constraint should invoke.
Returns the AVD::ConstraintValidator.class
that should handle validating self
.