NAME
Valiant::Validator::Object - Verify a related object
SYNOPSIS
package Local::Test::Address;
use Moo;
use Valiant::Validations;
has street => (is=>'ro');
has city => (is=>'ro');
has country => (is=>'ro');
validates ['street', 'city'],
presence => 1,
length => [3, 40];
validates 'country',
presence => 1,
inclusion => [qw/usa uk canada japan/];
package Local::Test::Person;
use Moo;
use Valiant::Validations;
has name => (is=>'ro');
has address => (is=>'ro');
has car => (is=>'ro');
validates name => (
length => [2,30],
format => qr/[A-Za-z]+/, #yes no unicode names for this test...
);
validates address => (
presence => 1,
object => {
nested => 1,
isa => 'Local::Test::Address',
}
);
DESCRIPTION
Runs validations on an object which is assigned as an attribute and aggregates those errors (if any) onto the parent object.
Useful when you need to validate an object graph or nested forms.
If your nested object has a nested object it will follow all the way down the rabbit hole Just don't make self referential nested objects; that's not tested and likely to end poorly. Patches welcomed.
ATTRIBUTES
This validator supports the following attributes:
nested
A boolean that specifies if we should run 'validates' on the object. Default is false.
type_constraint
Reference to a Type::Tiny style type constraint. If specified then the object must pass the constraint.
type_constraint_violation_msg
The message we return when 'type_constraint' fails. We pass 'display_name' and 'error_message' as options to the tag.
isa
The name of a class that the object should inherit from
wrong_inheritance_msg
The message we return when 'isa' fails. We pass 'parent' (the name of the class we require inheritance from) as options to the tag.
role
A role that the object is expected to consume
not_role_msg
The message we return when 'role' fails. We pass 'rolw' (the name of the role we require to consume from) as options to the tag.
invalid_msg
The error message returned when the object has nested validation errors.
not_blessed_msg
The error returned when the value is not an object
SHORTCUT FORM
This validator supports the follow shortcut forms:
validates attribute => ( object => 1, ... );
Which is the same as:
validates attribute => (
object => {
nested => 1,
}
);
<Note: you can use the 'nested' alias for '1' here if you want.
You can also specify a type constraint:
use use Types::Standard 'Str';
validates attribute => ( object => Str, ... );
Which is the same as:
use use Types::Standard 'Str';
validates attribute => (
object => {
type_constraint => Str,
}
);
AGGREGATED ERROR MESSAGES
When you nest a object with validations as in the following example any error messages in the nested object are imported into the parent object:
package Local::Test::Address;
use Moo;
use Valiant::Validations;
has street => (is=>'ro');
has city => (is=>'ro');
has country => (is=>'ro');
validates ['street', 'city'],
presence => 1,
length => [3, 40];
validates 'country',
presence => 1,
inclusion => [qw/usa uk canada japan/];
package Local::Test::Person;
use Moo;
use Valiant::Validations;
has name => (is=>'ro');
has address => (is=>'ro');
validates name => (
length => [2,30],
format => qr/[A-Za-z]+/, #yes no unicode names for this test...
);
validates address => (
presence => 1,
object => {
nested => 1,
}
);
my $address = Local::Test::Address->new(
city => 'NY',
country => 'Russia'
);
my $person = Local::Test::Person->new(
name => '12234',
address => $address,
);
my $address_errors = +{ $person->address->errors->to_hash(full_messages=>1) };
# $address_errors = +{
# 'country' => [
# 'Country is not in the list'
# ],
# 'city' => [
# 'City is too short (minimum is 3 characters)'
# ],
# 'street' => [
# 'Street can\'t be blank',
# 'Street is too short (minimum is 3 characters)'
# ],
# };
my $person_errors = +{ $person->errors->to_hash(full_messages=>1) };
# $address_errors = +{
# name => [
# "Name does not match the required pattern",
# ],
# address => [
# "Address Is Invalid",
# ],
# "address.city" => [
# "Address City is too short (minimum is 3 characters)",
# ],
# "address.country" => [
# "Address Country is not in the list",
# ],
# "address.street" => [
# "Address Street can't be blank",
# "Address Street is too short (minimum is 3 characters)",
# ],
};
When accessing errors for display you'll have to choose which access approach is best for your application.
Please note that you can have objects nested inside of objects so this can lead to very complex error messaging.
GLOBAL PARAMETERS
This validator supports all the standard shared parameters: if
, unless
, message
, strict
, allow_undef
, allow_blank
.
SEE ALSO
Valiant, Valiant::Validator, Valiant::Validator::Each.
AUTHOR
See Valiant
COPYRIGHT & LICENSE
See Valiant