Re: [Catalyst] Re: Validating single arg id

2009-10-21 Thread Bill Moseley
On Wed, Oct 21, 2009 at 6:52 AM, Aristotle Pagaltzis pagalt...@gmx.dewrote:

 * Zbigniew Lukasiak zzb...@gmail.com [2009-10-21 14:15]:
  What is the advantage of this over:
 
  sub view : Local {
   my ( $self, $c, $id ) = @_;
   $self-start( $c, $id );
   # do something with $c-stash-{obj}
   return 1;
  }

 Consider `/forum/7/topic/13/post/4/editform`. The end point in
 that chain would be

sub editform : Chained('post') {
my ( $self, $c ) = @_;
# ...
}

 The equivalent URI with Local would be `/editpost/7/13/4` and the
 action would look like this:

sub editform : Local {
my ( $self, $c, $forum, $topic, $post ) = @_;
$self-load_post( $forum, $topic, $post );
# ...
}


I think that depends on your data.  If $forum, $topic, and $post make up a
path on disk then yes, the chain is really useful.
If $post is a primary key and there's a relationship $post-topic-forum
then there's no need for those, of course, and confusion if $post-topic is
not the same id as passed in the URL for the forum.

Perhaps a good use for the chain there is for access control -- the current
user might only have access to some forums so a chain makes it easy to do
that kind of validation early in the chain and then detach if access fails.

The chain also allows fetching the $forum and $topic objects and place them
in the stash.  But, again if they are related can load the $post with a join
and avoid separate calls to the database.  (But, it may be the case that
caching the $forum and $topic individually make sense.)

Anyway, my actions often look like this: (a bit oversimplified)

package MyApp::Forum::Post;
sub view : Local {
my ( $self, $c, $post_id ) = @_;

$c-stash-{post} = $c-user-fetch_post( $id ) || return
$c-res-status( 404 );
}

Kind of ugly calling that on the user object, but it's just an example.
That method, for example, might do a join with the forum and topic tables
and also with a permissions table to make sure the user can access the post.

I do prefer the /forum/post/334/view type of URLs, though, but my CRUD
actions often end up like this:

   /forum/post - list
   /forum/post/edit  - create (POST)
   /forum/post/edit/22 - view (GET) update (PUT/POST)
   /forum/post/delete/22

And it's very DRY because there's separate model method for each.

The create method may have a different URL structure to specify the topic,
or it might be ?topic=123, or it might be part of the post parameters.





-- 
Bill Moseley
mose...@hank.org
___
List: Catalyst@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/


Re: [Catalyst] Re: Validating single arg id

2009-10-17 Thread Bill Moseley
On Sat, Oct 17, 2009 at 12:50 PM, Aristotle Pagaltzis pagalt...@gmx.dewrote:

 * iain iainhubb...@googlemail.com [2009-10-16 17:30]:
  until we did this we had boilerplate validation at the top of
  all the local actions.

 ++

 Bill, in another thread you asked me for an example of how
 Chained helps make things like complex auth checks more DRY. I’ve
 been meaning to respond with an example out of my $job codebase,
 but until I get around to it, here’s your hands-on example of
 something it’d buy your codebase immediately. :-)


I meant to respond about that.  Perhaps I'm missing something, but the
chained example works great if there multiple actions that need to get at
that Foo object.  They can all chain back to the same root which validates
the id and then fetches the Foo object with that id and stuffs it into the
stash.

But, its often the case (well, my case) that there's only *one* action that
fetches Foo, but there's also single actions for find()ing a number of other
objects.  If I'm following the chained example correctly, then there would
be root for each -- Foo, Bar, Baz, and so on each running basically the same
validation.  I suppose the root can be written in a way to fetch many
different object types by inspecting the current action and thus the fetch
for Foo, Bar, Baz, etc. objects could all have the same root of the chain.

If I have many actions that do $c-model( $whatever )-find( $id ) and I
want to validate id doesn't it seems like find() (or really search_rs() )
would be the method to override?

Perhaps a better approach would be add a safe_find() as J. Shirley
suggested, but what good are methods if you don't override them. ;)



-- 
Bill Moseley
mose...@hank.org
___
List: Catalyst@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/