I am trying to do a simple form validation in perl dancer but I was wondering what would be the best way to validate simple parameters (e.g. field cannot be empty, validity of the email, minimum length of a field) in dancer/perl without any extra plugin or CPAN module
here is the code so far
post '/register' => sub {
my $db = connect_db();
my $sql = 'insert into users (username, email, password, motivation) values (?, ?, ? ,?)';
my $sth = $db->prepare($sql) or die $db->errstr;
$sth->execute(params->{'username'}, params->{'email'},params->{'password'}, params->{'motivation'}) or die $sth->errstr;
set_flash('Hey you signed up !');
redirect '/thanks';
};
I did google it and I found several ways to do validation using CPAN modules like Form::Foo but how do it without that ?
I'm not sure why you'd want to expressly avoid using a plugin or a CPAN module - any solution you come up with will likely do the the same things as a plugin and/or CPAN module except that since it's new code it won't be as mature and tested.
I've recently started using Dancer to develop a simple app and I'll describe how I'm solving this problem using CPAN modules. You may of course choose to ignore it.
My route handler for adding a user looks like this:
post '/user/add' => {
my $args = valid_input('/user/add')
or return template('user/add');
my $user = User->new({
username => $args->{username},
# ...
});
user->insert; # you'll probably want some error handling here
set_flash('User added');
redirect '/user';
};
The valid_input
function is a helper I created for my app, which uses the Data::Form::Validator module from CPAN. The '/usr/add'
argument is the name of the validation profile to use - which for simplicity I decided to keep the same as the route name.
I won't bore you with the details of calling Data::Form::Validator since the documentation is pretty good. What I will mention is that in the event that validation fails, the valid_input
helper stores away the validation error messages for display in an alert box and also saves the submitted parameters:
my $q = params(); # need to force scalar context to get a hashref;
fill_in_form($q); # save submitted parameters
I have a before_template_render
hook that makes the saved validation error messages available to the template (they actually get rendered in views/layouts/main.tt
).
I also have an after_template_render
hook that takes the saved submitted parameters and puts them back into the rendered HTML form using the HTML::FillInForm module.
Since I have that infrastructure in place, the route handler to display an existing user record in an edit form with all the fields pre-populated is trivial:
get '/user/:id' => sub {
if( my $user = User->find( param('id') ) ) {
fill_in_form($user);
return template 'user/edit', { id => $user->id };
}
not_found "User not found";
};
The User
in User->find()
is another one of my app-specific helper functions. It uses the Dancer::Plugin::DBIC module to return a resultset object for my user
table.
I will say that I'm not necessarily a huge fan of Data::Form::Validator. I have been able to achieve everything I wanted but sometimes it does seem to take more work than I'd like.