Re: Data validation
[prev]
[thread]
[next]
[Date index for 2004/11/10]
On Wed, 10 Nov 2004 17:03:51 -0500, Perrin Harkins <perrin@xxxx.xxx> wrote:
> On Wed, 2004-11-10 at 09:56, Drew Taylor wrote:
> > The only big thing left on my todo list
> > is a way to get the templates (TT of course) to automatically include
> > the error messages - "[% err_element_name %] beside the form elements.
>
> I set DFV to use specific prefixes so I could grab what I want. This
> passes the messages to a template (HTML::Template here, but the
> principle is the same):
This is very similar to what I do as well (except that I use TT
instead of HTML::Template). I really like the ability for the
template to decide what the error message should say.
sub createUser_action {
my $self = shift;
my $tt_vars = shift || {};
my $profile = {
required => [qw( name email age )],
constraints => {
age => 'RE_num_int',
email => [
{ name => 'format', constraint => 'email' },
{ name => 'exists', constraint =>
sub { !MyDB::Users->search(email => lc shift); }
}
],
},
missing_optional_valid => 1,
};
my $results = Data::FormValidator->check($self->query, $profile);
if ($results->has_invalid or $results->has_missing) {
# Add the error messages to the template
# get 'invalid' elements as a hashref, and then convert any
arrayrefs to hashrefs
$tt_vars->{invalid} = $results->invalid;
foreach my $key (keys %{$tt_vars->{invalid}}) {
if (ref $tt_vars->{invalid}->{$key} eq 'ARRAY') {
$tt_vars->{invalid}->{$key} = {
map { $_ => 1 } @{ $tt_vars->{invalid}->{$key} }
};
}
}
# get 'missing' elements and convert to hashref
$tt_vars->{missing} = { map { $_ => 1 } $results->missing };
$self->log->debug("Form errors found - redirecting back to createUser");
return $self->createUser($tt_vars);
} else {
# everything is filled in correctly so save it in the session
my $valid = $results->valid;
$self->log->debug("Form params validated - creating user ".$valid->{name});
my $user = MyDB->do_transaction( sub {
$self->site->add_to_users( $valid );
} );
$tt_vars->{new_user} = $user;
return $self->tt_process($self->template_filename, $tt_vars);
}
}
This looks like a lot of work, but most of the above is actually
abstracted into a couple of method calls. I have inlined all of the
code to show what all actually happens.
The template looks very similar to what you have as well:
[% IF invalid || missing %]
<div style="text-align: center; color: red; font-size: 80%">
[% IF invalid.email.format %]The email address you provided does not
look valid<br />[% END %]
[% IF invalid.email.exists %]The email address you provided is already
registered<br />[% END %]
[% IF invalid.age %]Your age must be entered as a number<br />[% END %]
[% IF missing.email %]You have to provide an email address<br />[% END %]
[% IF missing.name %]You have to provide your name<br />[% END %]
[% IF missing.age %]You have to provide your age<br />[% END %]
</div>
[% END %]
[% IF invalid.email.exists %]<p style="text-align: center; color:
red">The email address you provided has already been registered. If
you have forgotten your password, you can <a href="[% url(
rm='forgotten_password' user=user.id ) %]">click here</a> to recover
your password.</p>[% END %]
I have to agree with you that moving the validation that
Data::FormValidator does into the Class::DBI modules would
unnecesarily complicate things, hence I still do all my validation at
the controller level. Ideally Class::DBI would do the work, but I
haven't found a clean way of fitting that into my development plan. I
really have no desire to eval and parse error messages to figure out
which parameters failed and why. I guess it could be done with
exception objects, but it still seems much more complicated...
If anyone has any good ideas on how to do D::FV like validation in
Class::DBI I would really like to hear them.
Cheers,
Cees Hek
|
(message missing)
|