1 package Reaction::UI::Controller::Collection::CRUD;
5 use base 'Reaction::UI::Controller::Collection';
8 use aliased 'Reaction::UI::ViewPort::Action';
10 sub _build_action_viewport_map {
11 my $map = shift->next::method(@_);
12 map{ $map->{$_} = Action } qw/create update delete delete_all/;
16 sub _build_action_viewport_args {
17 my $args = shift->next::method(@_);
19 { action_prototypes =>
20 [ { label => 'Create', action => sub {
21 [ '', 'create', $_[1]->req->captures ] } },
22 { label => 'Delete all', action => sub {
23 [ '', 'delete_all', $_[1]->req->captures ] } },
26 { action_prototypes =>
27 [ { label => 'View', action => sub {
28 [ '', 'view', [ @{$_[1]->req->captures}, $_[0]->__id ] ] } },
29 { label => 'Edit', action => sub {
30 [ '', 'update', [ @{$_[1]->req->captures}, $_[0]->__id ] ] } },
31 { label => 'Delete', action => sub {
32 [ '', 'delete', [ @{$_[1]->req->captures}, $_[0]->__id ] ] } },
39 sub get_model_action {
40 my ($self, $c, $name, $target) = @_;
42 if ($target->can('action_for')) {
43 return $target->action_for($name, ctx => $c);
46 #can we please kill this already?
47 my $model_name = "Action::${name}".$self->model_name;
48 my $model = $c->model($model_name);
49 confess "no such Model $model_name" unless $model;
50 return $model->new(target_model => $target, ctx => $c);
53 sub create :Chained('base') :PathPart('create') :Args(0) {
56 next_action => 'list',
57 on_apply_callback => sub { $self->after_create_callback($c => @_); },
59 $c->forward( basic_model_action => [$vp_args]);
62 sub delete_all :Chained('base') :PathPart('delete_all') :Args(0) {
64 $c->forward(basic_model_action => [{ next_action => 'list'}]);
67 sub after_create_callback {
68 my ($self, $c, $vp, $result) = @_;
69 return $self->redirect_to
70 ( $c, 'update', [ @{$c->req->captures}, $result->id ] );
73 sub update :Chained('object') :Args(0) {
75 #this needs a better solution. currently thinking about it
76 my @cap = @{$c->req->captures};
77 pop(@cap); # object id
78 my $vp_args = { next_action => [ $self, 'redirect_to', 'list', \@cap ]};
79 $c->forward(basic_model_action => [$vp_args]);
82 sub delete :Chained('object') :Args(0) {
84 #this needs a better solution. currently thinking about it
85 my @cap = @{$c->req->captures};
86 pop(@cap); # object id
87 my $vp_args = { next_action => [ $self, 'redirect_to', 'list', \@cap ]};
88 $c->forward(basic_model_action => [$vp_args]);
91 sub basic_model_action :Private {
92 my ($self, $c, $vp_args) = @_;
94 my $target = exists $c->stash->{object} ?
95 $c->stash->{object} : $self->get_collection($c);
97 my $cat_action_name = $c->stack->[-2]->name;
98 my $im_action_name = join('', (map{ ucfirst } split('_', $cat_action_name)));
99 return $self->push_viewport
101 $self->action_viewport_map->{$cat_action_name},
102 model => $self->get_model_action($c, $im_action_name, $target),
104 %{ $self->action_viewport_args->{$cat_action_name} || {} },