On Fri, Oct 16, 2009 at 5:24 PM, iain <iainhubb...@googlemail.com> wrote: > Bill Moseley wrote: >> >> I have a number of methods that start something like this: >> >> sub view : Local Args(1) { >> my ( $self, $c, $id ) = @_; >> >> my $obj = $c->model( 'DB::Foo' )->find( $id ) >> || return $c->res->status( 404 ); >> >> If $id is not valid then I might, as in that example, return with a 404 >> status. >> >> Of course, if $id is suppose to be an integer and a non-integer or an >> integer out of range is provided then the the database will throw an >> exception, which I want to prevent. I want valid ids to return an object >> and *anything* else to return undef before hitting the database. >> >> This is pretty low-level validation -- just validating primary key. For >> more complex validation I use a form validation module. >> >> Obviously, I could do something like >> >> return $c->res->status(404) unless $c->model('DB::Foo')->is_valid_id( $id >> ) >> >> in every method, but that's not very DRY. >> >> What I've done in the past is override the find() or search() method in my >> model base class so that whatever $id is passed it is validated. Specific >> model classes can override the is_valid_id() method if they use keys that >> are not a common key format (i.e. different integer range or non-integer >> key). >> >> What's you approach to validating that $id in situations like this where >> there's a single id? >> >> Do you just let the database throw the exception? I prefer to return 404s >> for invalid ids, regardless of their format (and likewise for ids that point >> to valid object, but are not owned by the current user instead of a 403). >> > > We did this sort of thing until we started to use chained actions. > Now we validate once at the start of the chain e.g. > > sub start : Chained('/') CaptureArgs(0) { > my ( $self, $c ) = @_; > # your validation here > my $obj = $c->model( 'DB::Foo' )->find( $id ) > || return $c->res->status( 404 ); > > $c->stash->{obj} = $obj; > > return 1; > } > > sub view : Chained('start') Args(0) { > my ( $self, $c ) = @_; > # do something with $c->stash->{obj} > return 1; > }
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; } -- Zbigniew Lukasiak http://brudnopis.blogspot.com/ http://perlalchemy.blogspot.com/ _______________________________________________ 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/