[Catalyst] Validating single arg id
iain
iainhubbard at googlemail.com
Fri Oct 16 15:24:54 GMT 2009
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;
}
until we did this we had boilerplate validation at the top of all the
local actions.
Iain.
More information about the Catalyst
mailing list