1 package Reaction::UI::Controller::Collection::CRUD;
5 use base 'Reaction::UI::Controller::Collection';
8 use aliased 'Reaction::UI::ViewPort::Action';
9 use aliased 'Reaction::UI::ViewPort::ListView';
11 sub _build_action_viewport_map {
13 my $map = $self->next::method(@_);
14 $map->{list} = ListView if exists $map->{list};
16 #my %allowed = map { $_ => undef }
17 # ( @{$self->default_member_actions}, @{$self->default_collection_actions} );
18 my @local_actions = qw/create update delete delete_all/;
19 #$map->{$_} = Action for grep { exists $allowed{$_} } @local_actions;
21 $map->{$_} = Action for @local_actions;
25 sub _build_default_member_actions {
26 [ @{shift->next::method(@_)}, qw/update delete/ ];
29 sub _build_default_collection_actions {
30 [ @{shift->next::method(@_)}, qw/create delete_all/ ];
33 sub get_model_action {
34 my ($self, $c, $name, $target) = @_;
35 return $target->action_for($name, ctx => $c);
38 sub create :Chained('base') :PathPart('create') :Args(0) {
41 on_apply_callback => sub { $self->after_create_callback($c => @_); },
42 on_close_callback => sub { $self->on_create_close_callback($c => @_) }
44 $self->basic_model_action( $c, $vp_args);
47 sub delete_all :Chained('base') :PathPart('delete_all') :Args(0) {
49 $self->basic_model_action( $c, {
50 on_close_callback => sub { $self->on_delete_all_close_callback($c => @_) }
54 sub on_delete_all_close_callback {
56 $self->redirect_to($c, 'list');
59 sub after_create_callback {
60 my ($self, $c, $vp, $result) = @_;
61 return $self->redirect_to
62 ( $c, 'update', [ @{$c->req->captures}, $result->id ] );
65 sub on_create_close_callback {
66 my($self, $c, $vp) = @_;
67 $self->redirect_to( $c, 'list' );
70 sub update :Chained('object') :Args(0) {
73 on_close_callback => sub { $self->on_update_close_callback($c => @_ ) }
75 $self->basic_model_action( $c, $vp_args);
78 sub on_update_close_callback {
80 #this needs a better solution. currently thinking about it
81 my @cap = @{$c->req->captures};
82 pop(@cap); # object id
83 $self->redirect_to($c, 'list', \@cap);
86 sub delete :Chained('object') :Args(0) {
89 on_close_callback => sub { $self->on_update_close_callback($c => @_) }
91 $self->basic_model_action( $c, $vp_args);
94 sub basic_model_action {
95 my ($self, $c, $vp_args) = @_;
97 my $target = exists $c->stash->{object} ?
98 $c->stash->{object} : $self->get_collection($c);
100 my $action_name = join('', map{ ucfirst } split('_', $c->stack->[-1]->name));
101 my $model = $self->get_model_action($c, $action_name, $target);
102 return $self->basic_page($c, { model => $model, %{$vp_args||{}} });
111 Reaction::UI::Controller::CRUD - Basic CRUD functionality for Reaction::InterfaceModel data
115 Controller class which extends L<Reaction::UI::Controller::Collection> to
116 provide basic Create / Update / Delete / DeleteAll actions.
118 Building on the base of the Collection controller this controller allows you to
119 easily create complex and highly flexible CRUD functionality for your
120 InterfaceModel models by providing a simple way to render and process your
121 custom InterfaceModel Actions and customize built-ins.
125 =head2 get_model_action $c, $action_name, $target_im
127 Get an instance of the C<$action_name>
128 L<InterfaceModel::Action|Reaction::InterfaceModel::Action> for model C<$target>
129 This action is suitable for passing to an
130 C<Action|Reaction::UI::ViewPort::Action> viewport
132 =head2 after_create_callback $c, $vp, $result
134 When a <create> action is applied, move the user to the new object's,
137 =head2 basic_model_action $c, \%vp_args
139 Extension to C<basic_page> which automatically instantiates an
140 L<InterfaceModel::Action|Reaction::InterfaceModel::Action> with the right
141 data target using C<get_model_action>
143 =head2 _build_action_viewport_map
145 Map C<create>, C<update>, C<delete> and C<delete_all> to use the
146 L<Action|Reaction::UI::ViewPort::Action> viewport by default and have C<list>
147 use L<ListView|Reaction::UI::ViewPort::ListView> by default.
149 =head2 _build_default_member_actions
151 Add C<update> and C<delete> to the list of default actions.
153 =head2 _build_default_collection_actions
155 Add C<create> and C<delete_all> to the list of default actions.
161 Chaned to C<base>. Create a new member of the collection represented by
162 this controller. By default it attaches the C<after_create_callback> to
163 DWIM after apply operations.
165 See L<Create|Reaction::InterfaceModel::Action::DBIC::ResultSet::Create>
170 Chained to B<base>, delete all the members of the B<collection>. In most cases
171 this is very much like a C<TRUNCATE> operation.
173 See L<DeleteAll|Reaction::InterfaceModel::Action::DBIC::ResultSet::DeleteAll>
178 Chained to C<object>, update a single object.
180 See L<Update|Reaction::InterfaceModel::Action::DBIC::Result::Update>
185 Chained to C<object>, delete a single object.
187 See L<Delete|Reaction::InterfaceModel::Action::DBIC::Result::Delete>
192 L<Reaction::UI::Controller::Collection>, L<Reaction::UI::Controller>
196 See L<Reaction::Class> for authors.
200 See L<Reaction::Class> for the license.