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