[Catalyst] Re: Ajax, Jemplate, forms, rest & data validatio

J. Shirley jshirley at gmail.com
Tue May 27 15:46:12 BST 2008


On Mon, May 26, 2008 at 10:03 AM, James. L <perlwle at yahoo.com> wrote:
> On Fri, May 23, 2008 at 3:10 PM, Henry Drinkwater
> <henry.drinkwater[at]googlemail.com> wrote:
>
> [snip]
>
> On the validation note, I use Data::FormValidator in
> conjunction with
> a DBIx::Class ResultSet - still in the model, in that
> it is outside of
> the Catalyst scope. Easier to unit test this stuff,
> too, since you
> don't have to muck with a controller. Lots of other
> folk use
> FormBuilder or FormFu, so it is really just picking
> what makes the
> most sense to you.
>
> Good luck,
> -J
> ===================================================
>
> hi,
>
> i am using D::F in controller only then rely on the
> database(sometimes little bit on model) to die on
> unexpected data.
>
> I am interested in how you managed to use
> Data::FormValidator in conjunction with a DBIx::Class
> ResultSet.. do you still do form validation in
> controller? how do you map the error from model to
> webGUI?
>
> thanks!
>
> James.
>
>
>
>


The basic idea is that you have a base schema class, rather than all
of your schema classes doing:
use base qw/DBIx::Class/;

Instead, something like this (naming rather verbose, just to be clear):
use base qw/MyApp::Base::Schema::Class/;

In there, you assign the ResultSet.  Because of the order of
operations in DBIC, the way to have a base schema class setup a custom
ResultSet class is to run something after table.  In the easiest of
ways (and not very pretty):

package MyApp::Base::Schema::Class;

use base 'DBIx::Class';

sub table {
    my $class = shift;
    $class->next::method(@_);
    # Automatically populate the resultset to include serialization.
    $class->resultset_class('MyApp::ResultSet::Validate')
        if $class->resultset_class eq 'DBIx::Class::ResultSet';
}

1;

Now, you have a custom resultset class that gets loaded by default.
Ideally, you'll not use this globally but name it like
Class::WithValidate or something.

Then inside of the resultset, just create a ->validate method that you
can call.    A very basic validate method (that just returns the valid
data, you could pass it onwards to a $self->create($data)):

sub validate {
    my ( $self, $data, $profile ) = @_;
    my $results = Data::FormValidator->check($data, $profile);

    if ( $results->has_invalid or $results->has_missing ) {
        die $results;
    }
    return scalar $results->valid;
}

How you determine how to store your $profile is up to you, and there
are way too many ways to do it.  If inside of Catalyst,
__PACKAGE__->config->profiles->{create} seems reasonable enough.

I'm curious what others on the list think of this.  I've never been
pleased enough with it to bake it for public eyes, and it doesn't
evolve fast enough for me to seek feedback.



More information about the Catalyst mailing list