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