[Catalyst] Can't seem to use forward or detach. Any special requirements?

kakimoto at tpg.com.au kakimoto at tpg.com.au
Mon Apr 27 22:29:47 GMT 2009


Hello, Mr Wells,

   Good morning and a big thank you for your reply.
It was pretty accurate. Last night, I managed to get my problem fixed by
using a redirect
prior to receiving your reply.

 Basically, my solution was conceptually on the same lines as the
proposed solution
which you had given.

1) Web browser requests for /user/subscriptions/add,
2) Catalyst controller (sub add) finds that it's just an initialisation
hence
    works out some required hidden ids and stores them into the stash.
3) A template, add.tt2 gets used to render a web form for input
4) Approapriate input gets entered by the user and user clicks on the
submit button.
5) Catalyst controller (sub add) finds that it's a submission (by means
of the request method
   being a POST) and performs data validation and creates new database
table entry if
   validation was successful.
6) The new entry's database ID (primary key) and a predefined mesage of
success then gets placed in      the flash along.
7) Catalyst controller then performs a redirect to 
/user/subscriptions/added.
8) A call to detach (ie. "$c->detach ();") appears right after the
redirect statement.
     My code looks like this:

            $c->log->debug(q{   Entry processed.});
            $c->res->redirect($c->uri_for('/users/subscriptions/added '));
            $c->detach ();


9) As soon as the redirect takes place, another catalyst controller,
'sub added :Local '
    gets called and yes, a template , added.tt2 gets used for rendering.

It works and I have regression tests made when  I was developing the
controller to
make sure it acts as it should. All good there:)


Problem I was trying to solve:
------------------------------------

 - To use one controller as much as possible for adding a new entry.
- Problem is that if anyone should hit the F5 key or refresh button on their
    browser after a successful entry into the database ( where a message
of success
   gets shown and request parameters are still active), an unintended
new entry gets 
   created on the database table.
 -  I tried many ways (ie setting flags in the flash upon successful
creation of
   a database entry) but they have seem to fail . I have also tried
forwarding
   and detaching to no success.


A question on your proposed solution
-------------------------------------------


> Web browser asks for /user/subscriptions/add, posting parameters, in
> order to create a new row in the DB.
> => On the server, your website code creates a new row in the DB
> => Server outputs a redirect to a page that lists the objects, let's
> say /user/subscriptions/list and calls detach() without outputting a
> page at all.   (No template is called.)


Assuming that when the browser asks for /user/subscriptions/add
 (along with the necessary posting parameters), the controller called is
sub add. I would assume that when you mention that 'No template is called',
that's on the same controller (ie sub add). Am I correct?



 Thank you again for your time and patience, everyone.


K. akimoto.










Quoting Ian Wells <ijw at cack.org.uk>:

> 2009/4/27  <kakimoto at tpg.com.au>:
> > Hello, J. Shirley,
> >
> >  Thank you for your explaination. It made things much clearer and
> > confirmed a lotta things.
> 
> Akimoto-san,
> 
> people have been answering the questions that you've asked, but I
> wanted to check up what it is that you're trying to do.
> 
> Tell me if I have this right:
> 
> 1. the problem you're trying to avoid:
> 
> Web browser asks for /user/subscriptions/add, posting parameters, in
> order to create a new row in the DB.
> => On the server, your website code creates a new row in the DB
> => Server outputs a list of objects.
> 
> Guy using web browser presses refresh, to show the list again
> => On the server, your website code creates a new row in the DB
> (which
> the user didn't want).
> => Server outputs a list of objects.
> 
> 2. the way you're trying to avoid it
> 
> I'm not quite sure *what* you're trying to do, but it's a bit
> confused, so let's sklip to
> 
> 
> 3. the way you *should* be doing it
> 
> Web browser asks for /user/subscriptions/add, posting parameters, in
> order to create a new row in the DB.
> => On the server, your website code creates a new row in the DB
> => Server outputs a redirect to a page that lists the objects, let's
> say /user/subscriptions/list and calls detach() without outputting a
> page at all.   (No template is called.)
> 
> Web browser receives redirect, asks for the page that lists the
> objects. at /user/subscriptions/list
> => Server outputs a list of objects.
> 
> Guy using web browser presses refresh, to show the list again (and
> note that because of the redirect this now loads
> /user/subscriptions/list)
> => Server outputs a list of objects.
> 
> 
> People are steadily trying to steer you towards (3) above.  In (3)
> you
> shouldn't be passing all the parameters to the create operation to
> the
> list page (e.g. the new object name doesn't need to go to the list
> page), so they shouldn't be on the redirect.  However, you might
> have
> filters and sort arguments for the list that should be passed on -
> typically these are added to the redirect URL rather than passed on
> in
> the stash.  You might also have a message you want to print,
> reporting
> on the *immediately preceding* operation that created the object,
> there.  *That* would go in the flash.
> 
> Does that help?
> 
> Cheers,
> -- 
> Ian.
> 
> _______________________________________________
> List: Catalyst at lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive:
> http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
> 
> 
> 






More information about the Catalyst mailing list