move the error to the action
[catagits/Reaction.git] / lib / Reaction / InterfaceModel / Action.pm
1 package Reaction::InterfaceModel::Action;
2
3 use Reaction::Meta::InterfaceModel::Action::Class;
4 use metaclass 'Reaction::Meta::InterfaceModel::Action::Class';
5
6 use Reaction::Meta::Attribute;
7 use Reaction::Class;
8
9 use namespace::clean -except => [ qw(meta) ];
10
11 has error_message => (
12   is => 'rw',
13   isa => 'Str',
14   metaclass => 'Reaction::Meta::Attribute'
15 );
16 has target_model => (
17   is => 'ro',
18   required => 1,
19   metaclass => 'Reaction::Meta::Attribute'
20 );
21
22 has ctx => (
23   isa => 'Catalyst',
24   is => 'ro',
25   lazy_fail => 1,
26   metaclass => 'Reaction::Meta::Attribute',
27   weak_ref => 1,
28 );
29
30 sub parameter_attributes {
31   shift->meta->parameter_attributes;
32 }
33
34 sub parameter_hashref {
35   my ($self) = @_;
36   my %params;
37   foreach my $attr ($self->parameter_attributes) {
38     my $reader = $attr->get_read_method;
39     my $predicate = $attr->get_predicate_method;
40     next if defined($predicate) && !$self->$predicate
41          && ($attr->is_lazy_fail || !$attr->has_default);
42     $params{$attr->name} = $self->$reader;
43   }
44   return \%params;
45 }
46
47 sub can_apply {
48   my ($self) = @_;
49   foreach my $attr ($self->parameter_attributes) {
50     my $predicate = $attr->get_predicate_method;
51     if ($self->attribute_is_required($attr)) {
52       confess "No predicate for required attribute ${\$attr->name} for ${self}"
53         unless $predicate;
54       return 0 if !$self->$predicate && ($attr->is_lazy_fail || !$attr->has_default);
55     }
56     if ($attr->has_valid_values) {
57       unless ($predicate && !($self->$predicate)) {
58         my $reader = $attr->get_read_method;
59         return 0 unless $attr->check_valid_value($self, $self->$reader);
60       }
61     }
62   }
63   return 1;
64 };
65 sub error_for {
66   my ($self, $attr) = @_;
67   confess "No attribute passed to error_for" unless defined($attr);
68   unless (ref($attr)) {
69     my $meta = $self->meta->find_attribute_by_name($attr);
70     confess "Can't find attribute ${attr} on $self" unless $meta;
71     $attr = $meta;
72   }
73   return $self->error_for_attribute($attr);
74 };
75 sub error_for_attribute {
76   my ($self, $attr) = @_;
77   my $reader = $attr->get_read_method;
78   my $predicate = $attr->get_predicate_method;
79   if ($self->attribute_is_required($attr)) {
80     unless ($self->$predicate) {
81       return $attr->name." is required";
82     }
83   }
84   if ($self->$predicate && $attr->has_valid_values) {
85     unless ($attr->check_valid_value($self, $self->$reader)) {
86       return "Not a valid value for ".$attr->name;
87     }
88   }
89   return; # ok
90 };
91 sub attribute_is_required {
92   my ($self, $attr) = @_;
93   return $attr->is_required;
94 };
95
96 sub sync_all { }
97
98 __PACKAGE__->meta->make_immutable;
99
100
101 1;
102
103 =head1 NAME
104
105 Reaction::InterfaceModel::Action
106
107 =head1 SYNOPSIS
108
109 =head1 DESCRIPTION
110
111 =head2 target_model
112
113 =head2 ctx
114
115 =head2 parameter_attributes
116
117 =head1 SEE ALSO
118
119 L<Reaction::Meta::Attribute>
120
121 =head1 AUTHORS
122
123 See L<Reaction::Class> for authors.
124
125 =head1 LICENSE
126
127 See L<Reaction::Class> for the license.
128
129 =cut