[Catalyst] Multiple chaining to same action ...

J. Shirley jshirley at gmail.com
Mon Feb 15 21:08:30 GMT 2010


On Mon, Feb 15, 2010 at 12:38 PM, Kiffin Gish <kiffin.gish at planet.nl> wrote:
> In my application, users are allowed to edit only their own settings
> like this:
>
> /account/id/client/settings/edit
>
> | /role/*/settings/edit | /auth (0)                       |
> |                       | -> /role/base (1)               |
> |                       | -> /role/settings/crud/base (0) |
> |                       | => /role/settings/crud/edit     |
>
> # Controller::Role
> sub base : Chained('/auth') PathPart('role') CaptureArgs(1) {
>    my ( $self, $c, $id ) = @_;
>
>    # Get the user if possible.
>    my $user = $c->model('DB::User')->find($id);
>
>    # Make sure that the user is indeed this user.
>    $c->detach('/error_403') unless $c->user->id == $id;
>
>    # Save the user in the stash.
>    $c->stash( user => $user );
> }
>
> # Controller::Role::Settings::CRUD
> sub base : Chained('/role/base') PathPart('settings') CaptureArgs(0)
> {...}
>
> sub edit : Chained('base') PathPart('edit') Args(0) {
>    my ( $self, $c ) = @_;
>    my $user = $c->stash->{user};
>    ....
> }
>
> Now the hard part.
>
> I also want to allow the admin to be able to edit all user settings in
> exactly the same way, like this:
>
> /account/id/admin/user/id/settings/edit
>
> # Controller::Role::Admin::User
> sub base : Chained('/role/admin/base') PathPart('user') CaptureArgs(0)
> {...}
>
> sub id : Chained('base') PathPart('') CaptureArgs(1) {
>    my ( $self, $c, $id ) = @_;
>
>    # Get the user if possible.
>    my $user = $c->model('DB::User')->find($id);
>
>    # Does this user exist?
>    $c->detach('/error_404') unless ($user);
>
>    # Save the user in the stash.
>    $c->stash( user => $user );
> }
>
> sub edit : Chained('base') PathPart('settings') Args(0) {...}
>
> As you can see there's alot of repetition going on and there must be a
> more elegant way to handle this.
>
> How does one go about chaining the same action from multiple points.
> Does this make sense and if so is it possible?
>
> Thanks alot in advance,
> Kiffin
>
>

Simply use roles or a base class.  Just go with a standard base class
if that's what you are more familiar with.

With Chained, this becomes very simple because you only have to define
the individual setup methods (sub base : Chained(...)) and go from
there.

You can look at Catalyst::Controller::DBIC::API for a CPAN'd example.

-J



More information about the Catalyst mailing list