[Catalyst] $c->res->redirect and $c->detach

Ash Berlin ash at cpan.org
Tue Sep 19 00:23:25 CEST 2006

John Napiorkowski wrote:
> --- Matt S Trout <dbix-class at trout.me.uk> wrote:
>> John Napiorkowski wrote:
>>> Hi,
>>> I have a controller with some chained actions. 
>> One of
>>> the actions (not an endpoint) will redirect given
>> a
>>> certain value for the arguments.  However I find
>> that
>>> this doesn't stop the chain from completing.  I
>> still
>>> get a line about the redirect in the log, but the
>>> endpoint in that chain still activates.
>>> I find that this doesn't happen when I use
>> $c->detach,
>>> although in this circumstance detach is not the
>> best
>>> use for me.
>>> Has anyone run into this before and found a way
>> around
>>> it?
>> Calling $c->res->redirect never stops anything from
>> completing, all it does is 
>> set the appropriate data on the response. $c->detach
>> is the correct thing to 
>> do here.
>> Perhaps you need to rephrase your question in terms
>> of why you feel detach 
>> isn't ideal and how that interacts with the way your
>> architecture is put together?
> It is probably more a case of my not understanding the
> best way to do this.  I'm still a bit stuck in my old
> way of putting these types of applications together. 
> Let me explain a little more what I am doing and
> perhaps this is solvable with a more catalyst-think
> solution.
> I'm using chained actions as part of a wiki system. 
> Basically I have actions that descend down a url which
> first finds a wiki (I have multiply wikis in the
> system) and then a wiki page and then an action
> associated, such as create, view or edit.  Now when I
> run the action associated with finding the page in the
> database based on the page title what I'd like to do
> is redirect to the create action when we don't find
> that a  page exists.  I think this is the best action
> for a wiki and what is expected (as long as you have
> create rights).
> Now I'd like the URL to actually change to represent
> that you are on an edit page, which is why the detach
> doesn't do it for me.  If this is really the best
> thing to do I guess I can bend my head around it, but
> I find in not so intuitive to have a give url show
> both content or a form.
> I find it easier to write the tests for this if I can
> detect the redirect action.
> Doing a $c->detach('/end') after the redirect was
> suggested to me, although I find this can give an
> error since my default end action looks for a template
> which is this case doesn't exist.
> Maybe I should do both a redirect and a detach?
> I can show you some code for this if that would help
> you understand my thinking, although it's in two
> different modules (I'm using the :Chained('.') feature
> to help organize the code and it works fantastically).
> Let me know what you think.  Thank you for your
> feedback and suggestions.  --john
I think the problem here is that you're expecting redirect to do more 
for you than it does:

       $res->redirect( $url, $status )

       Causes the response to redirect to the specified URL.

           $c->response->redirect( 'http://slashdot.org' );
           $c->response->redirect( 'http://slashdot.org', 307 );

Thats all it does. It doesn't stop the chain. Try this instead

$c->res->redirect($url); return 0;

Although I'm not sure if the `return 0' will dwim in chained dispatch. 
Try it and see.


More information about the Catalyst mailing list