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