move the error to the action
[catagits/Reaction.git] / lib / Reaction / InterfaceModel / Action.pm
index 55cdfbe..06ab55a 100644 (file)
@@ -6,83 +6,97 @@ use metaclass 'Reaction::Meta::InterfaceModel::Action::Class';
 use Reaction::Meta::Attribute;
 use Reaction::Class;
 
-class Action which {
-
-  has target_model => (is => 'ro', required => 1,
-                       metaclass => 'Reaction::Meta::Attribute');
-
-  has ctx => (isa => 'Catalyst', is => 'ro', required => 1,
-                metaclass => 'Reaction::Meta::Attribute');
-
-  implements parameter_attributes => as {
-    shift->meta->parameter_attributes;
-  };
-
-  implements parameter_hashref => as {
-    my ($self) = @_;
-    my %params;
-    foreach my $attr ($self->parameter_attributes) {
-      my $reader = $attr->get_read_method;
-      my $predicate = $attr->get_predicate_method;
-      next if defined($predicate) && !$self->$predicate;
-      $params{$attr->name} = $self->$reader;
-    }
-    return \%params;
-  };
-
-  implements can_apply => as {
-    my ($self) = @_;
-    foreach my $attr ($self->parameter_attributes) {
-      my $predicate = $attr->get_predicate_method;
-      if ($self->attribute_is_required($attr)) {
-        return 0 unless $self->$predicate;
-      }
-      if ($attr->has_valid_values) {
-        unless ($predicate && !($self->$predicate)) {
-          my $reader = $attr->get_read_method;
-          return 0 unless $attr->check_valid_value($self, $self->$reader);
-        }
-      }
-    }
-    return 1;
-  };
-
-  implements error_for => as {
-    my ($self, $attr) = @_;
-    confess "No attribute passed to error_for" unless defined($attr);
-    unless (ref($attr)) {
-      my $meta = $self->meta->find_attribute_by_name($attr);
-      confess "Can't find attribute ${attr} on $self" unless $meta;
-      $attr = $meta;
-    }
-    return $self->error_for_attribute($attr);
-  };
-
-  implements error_for_attribute => as {
-    my ($self, $attr) = @_;
+use namespace::clean -except => [ qw(meta) ];
+
+has error_message => (
+  is => 'rw',
+  isa => 'Str',
+  metaclass => 'Reaction::Meta::Attribute'
+);
+has target_model => (
+  is => 'ro',
+  required => 1,
+  metaclass => 'Reaction::Meta::Attribute'
+);
+
+has ctx => (
+  isa => 'Catalyst',
+  is => 'ro',
+  lazy_fail => 1,
+  metaclass => 'Reaction::Meta::Attribute',
+  weak_ref => 1,
+);
+
+sub parameter_attributes {
+  shift->meta->parameter_attributes;
+}
+
+sub parameter_hashref {
+  my ($self) = @_;
+  my %params;
+  foreach my $attr ($self->parameter_attributes) {
     my $reader = $attr->get_read_method;
     my $predicate = $attr->get_predicate_method;
+    next if defined($predicate) && !$self->$predicate
+         && ($attr->is_lazy_fail || !$attr->has_default);
+    $params{$attr->name} = $self->$reader;
+  }
+  return \%params;
+}
+
+sub can_apply {
+  my ($self) = @_;
+  foreach my $attr ($self->parameter_attributes) {
+    my $predicate = $attr->get_predicate_method;
     if ($self->attribute_is_required($attr)) {
-      unless ($self->$predicate) {
-        return $attr->name." is required";
-      }
+      confess "No predicate for required attribute ${\$attr->name} for ${self}"
+        unless $predicate;
+      return 0 if !$self->$predicate && ($attr->is_lazy_fail || !$attr->has_default);
     }
-    if ($self->$predicate && $attr->has_valid_values) {
-      unless ($attr->check_valid_value($self, $self->$reader)) {
-        return "Not a valid value for ".$attr->name;
+    if ($attr->has_valid_values) {
+      unless ($predicate && !($self->$predicate)) {
+        my $reader = $attr->get_read_method;
+        return 0 unless $attr->check_valid_value($self, $self->$reader);
       }
     }
-    return; # ok
-  };
+  }
+  return 1;
+};
+sub error_for {
+  my ($self, $attr) = @_;
+  confess "No attribute passed to error_for" unless defined($attr);
+  unless (ref($attr)) {
+    my $meta = $self->meta->find_attribute_by_name($attr);
+    confess "Can't find attribute ${attr} on $self" unless $meta;
+    $attr = $meta;
+  }
+  return $self->error_for_attribute($attr);
+};
+sub error_for_attribute {
+  my ($self, $attr) = @_;
+  my $reader = $attr->get_read_method;
+  my $predicate = $attr->get_predicate_method;
+  if ($self->attribute_is_required($attr)) {
+    unless ($self->$predicate) {
+      return $attr->name." is required";
+    }
+  }
+  if ($self->$predicate && $attr->has_valid_values) {
+    unless ($attr->check_valid_value($self, $self->$reader)) {
+      return "Not a valid value for ".$attr->name;
+    }
+  }
+  return; # ok
+};
+sub attribute_is_required {
+  my ($self, $attr) = @_;
+  return $attr->is_required;
+};
 
-  implements attribute_is_required => as {
-    my ($self, $attr) = @_;
-    return $attr->is_required;
-  };
+sub sync_all { }
 
-  sub sync_all { }
+__PACKAGE__->meta->make_immutable;
 
-};
 
 1;