A Catalyst controller can dispatch processing to another action using
$c->go. (This example will use
$c->go but the general approach should work for the others as well.) One way to invoke those methods is by passing them the private path to a Catalyst action.
Suppose you try to:
This will work fine if that path maps to
sub Baz() in the Foo::Bar controller, or
sub Bar() in the Foo controller (in which case 'baz' would get passed as an argument). However, if that path maps to the
default() action in e.g. the Foo controller, you will get:
Couldn't go("/foo/bar/baz"): Couldn't go to command "/foo/bar/baz": Invalid action or component.
To make that work correctly, you would instead have to modify the path like so:
but it is not obvious from looking at the original path how it might need to be modified.
Instead of passing the path directly to
$c->go, you can have the dispatcher create a Catalyst::Action from the path. The dispatcher will take into account whether the path maps to a
default() action at some depth. Then pass that action to
my $path = "/foo/bar/baz"; # some path to an action # Stuff the path into the current request: # $c->request->path($path); # Tell the dispatcher to create a new action. # # It will use $c->request->path to update # both $c->action and $c->request->args. # $c->dispatcher->prepare_action($c); $c->go($c->action, $c->request->args); # make sure to include the request args!
This should work fine if you are using
$c->go, which do not return to the caller upon completion. If you are using
$c->visit, you may want to save the state of
$c->request so they can be restored afterward.