[Catalyst] url parsing and sub controller

Bill Moseley moseley at hank.org
Tue Sep 6 15:16:52 CEST 2005


On Mon, Sep 05, 2005 at 10:22:27PM +0200, Andreas Marienborg wrote:
> Yes, as the default : Private actions are inheritable, and as such  
> you need to make sure you use
> the correct one. Think this has been debated before, atleast on IRC,  
> but cannot remember what the outcome was.

I've done some of that debating on #catalyst about default.  The
outcome was basically that I wanted to use "default" for something
that it wasn't really designed for.  My desire was to have "default"
act like a default local action for whatever controller the default
resides in.


> basicly the third argument to default is an array with every path- 
> element. So if you always want the last one, do my ($self, $c,  
> @args); and pick out the last one. If you want a specific one, use  
> that etc.

And that was my problem with default.  Unlike Local actions where the
code doesn't have to be aware of where it is in the controller name
space, default does have to know to be able to shift off the path
segments to get to the real arguments relative to the current
controller.

I'm still not clear why all the path arguments are passed to default --
that is, if it's a design feature or just the way default had to
work.


This was the discussion in July:

I needed to duplicate an existing URL mapping scheme from another
application.

I wanted a controller called MyApp::C::Path::To::Tables that did all
things related to "Tables", and I wanted to use local-style actions so
that later moving the controller to a new name space would not mean
rewriting the actions within the controller - i.e. actions were all
relative to the controller.

    /path/to/tables                 - list all tables
    /path/to/tables/users           - list all in users table
    /path/to/tables/users/21        - edit user 21
    /path/to/tables/users/21/update - and update user 21

I didn't know the table names ahead of time so I didn't have actions
for each table.  And that left "default" as a way to handle this.

If default worked like local (in how it returns @args) I could
handle the above like:

    sub default : Local {
        my ( $self, $c, $table_name, $id, $action ) = @_
    }

I "solved" this by using this ugliness in each controller's auto
action to shift off the path segments pointing to the controller
leaving just the arguments:

    $c->shift_args( __PACKAGE__ );


One problem with trying to use default as a default action in a
given controller is that another controller can take the action away.

Assuming no "users" action in MyApp::C::Path::To::Tables controller (i.e.
using default as above):

    /path/to/tables/users/21

gets handled by the default action in Tables.pm.  But if some day
MyApp::C::Path::To.pm defines a "tables" local action then the default
action will no longer work.

Of course, the same thing happens using Catalyst the "right" way:

    /path/to/tables/list/users/21

calls the list action with @args = users, 21.  The controller
App::C::Path::To::Tables::List with a "users" action will override
that.



-- 
Bill Moseley
moseley at hank.org




More information about the Catalyst mailing list