[html-formfu] Using DBIC Validation in FormFu

Serge Zaschipas serge at uacoders.com
Thu Oct 29 17:44:38 GMT 2009


Hi Carl,

So today found how to create my own errors on FormFu thats example of my
hacks ;-)

package HTML::FormFu::Model::DBIC::Validated;
use strict;
use warnings;
use base 'HTML::FormFu::Model::DBIC';
use Data::Dumper;
use DBIx::Class::Validation::Dictionary qw/hummable/;
use Carp qw( croak );
our $VERSION =3D '0.00001';
$VERSION =3D eval $VERSION;

sub submitted_and_valid {
    my ( $self, $dbic ) =3D @_;
    croak "row object missing" if !defined $dbic;
    my $form =3D $self->form;
    return undef unless $form->submitted();
    my $form_submitted_and_valid =3D $form->submitted_and_valid();
    HTML::FormFu::Model::DBIC::_save_columns( $form, $dbic, $form ) or
return;
    eval { $dbic->validate() };
    return $form_submitted_and_valid unless my $dbic_validation_result =3D =
$@;
    return $form_submitted_and_valid unless
$dbic_validation_result->has_error;
    my $errors =3D {};

    foreach my $key ( @{ $dbic_validation_result->error() } ) {
        my $comma =3D '';
        foreach my $type ( @{ $dbic_validation_result->error($key) } ) {
            $errors->{$key} .=3D $comma . hummable($type);
            $comma =3D ',';
        }
    }
    foreach my $field ( @{ $form->get_fields } ) {
        my $name =3D $field->nested_name;
        next unless defined $errors->{$name};
        my $base_validator;
        $base_validator =3D HTML::FormFu::Validator->new(
                             { type =3D> 'dynamicValidator', parent =3D> $f=
ield
} );
        push @{ $field->{_validators} }, $base_validator;
        my $error =3D
          HTML::FormFu::Exception::Validator->new(
                                                { message =3D>
$errors->{$name} },
          );
        $error->parent( $base_validator->parent );
        $error->validator($base_validator);
        $field->add_error($error);
    }
    return $form_submitted_and_valid &&
!$dbic_validation_result->has_error();
}

Best Regards
Sergiy Zaschipas

2009/10/29 Serge Zaschipas <serge at uacoders.com>

> Hi Carl,
> I just plays with FormFu to find solution of my problem.
> There is example what I want:
> 1) I want use DBIx::Class for model
> 2) I want use DBIx::Class::Validation as model validator
> This points I have done and checked in my example:
>
> package pf2::Schema::Result::Switch;
> use strict;
> use warnings;
> use base 'DBIx::Class';
>
> __PACKAGE__->load_components(qw/Core Validation/);
> __PACKAGE__->table("switch");
>
> #<there is my class definition>
>
> #thee is my Validation profile which must check 'name' field for UNIQUE in
> `switch` table;
> #in example used FormValidator::Simple::Plugin::DBIC::Unique;
>
> use FormValidator::Simple qw/DBIC::Unique/;
> $DBIx::Recordset::PreserveCase =3D 1;
> my $profile =3D sub {
>         my ($result) =3D @_;
>         return [
>               name =3D> [[ 'DBIC_UNIQUE', $result->result_source->results=
et,
> 'name']],
>             ];
> };
>
> __PACKAGE__->validation(
>     module =3D> 'FormValidator::Simple',
>     profile =3D> $profile,
>     filter =3D> 0,
>     auto =3D> 0,
> );
>
> #----------------------------
>
> When I use FormFu i do
>
> if($form->submitted_and_valid){
>   $form->model->update($switch);
> } else {
>  $form->model->default_values($switch);
> }
>
> So in my point of view inside submitted_and_valid must be DBIC validation
> too (fill some $_switch object and call $_switch->validate();)
> In case of errors they must be added as exceptions and properly displayed
> on form.
>
> I just play around and tried to implement it by inheritance of FormFu but
> yet have problems with adding exceptions to the form...
>
> in controller i will use next code
> if($form->model('DBIC::Validated')->submitted_and_valid($switch)){
>   $form->model->update($switch);
> } else {
>  $form->model->default_values($switch);
> }
>
> Also did some own class based on 'HTML::FormFu::Model::DBIC';
>
>
> package HTML::FormFu::Model::DBIC::Validated;
> use strict;
> use warnings;
> use base 'HTML::FormFu::Model::DBIC';
> use Data::Dumper;
>
> use Carp qw( croak );
>
> our $VERSION =3D '0.00001';
> $VERSION =3D eval $VERSION;
>
> sub submitted_and_valid{
>     my ($self, $dbic) =3D at _;
>     croak "row object missing" if !defined $dbic;
>     my $form =3D $self->form;
>
>     return undef unless $form->submitted();
>
>     my $form_submitted_and_valid =3D $form->submitted_and_valid();
>
>     HTML::FormFu::Model::DBIC::_save_columns($form, $dbic, $form ) or
> return;
>     eval { $dbic->validate() };
>     return $form_submitted_and_valid unless my $dbic_validation_result =
=3D
> $@;
>     return $form_submitted_and_valid unless
> $dbic_validation_result->has_error;
>     my $errors =3D{};
>
>     foreach my $key ( @{ $dbic_validation_result->error() } ) {
>         my $comma =3D '';
>         foreach my $type ( @{ $dbic_validation_result->error($key) } ) {
>             $errors->{$key} .=3D $comma."invalid: $key - $type ";
>             $comma =3D ','
>         }
>     }
>
>     foreach my $field ( @{ $form->get_fields } ){
>         my $name =3D  $field->nested_name;
>         next unless defined $errors->{$name};
>
> #PROBLEM A
> # there I have problem with adding error message on form element yet
>         my $error =3D HTML::FormFu::Exception::Validation->new({message
> =3D>'must be unique'});
>
>         #$error->validator($v);
>         #push @{$field->_validators}, $error;
>         $field->add_error($error);
>
>
>     }
>     return $form_submitted_and_valid &&
> !$dbic_validation_result->has_error();
> }
>
> 1;
>
> Maybe it is a little brutal solution as soon as i not fully investigated
> FormFu inside but in case if i can add on form field my custom message in
> PROBLEM A then i have acceptable solution for my task...
>
>
> 2009/10/29 Serge Zaschipas <serge at uacoders.com>
>
> 2009/10/27 Carl Franks <fireartist at gmail.com>
>>
>> Hi Sergiy,
>>>
>>> It would probably be possible to provide a compatible check() method,
>>> but I'm not sure how far it would get you.
>>>
>>> As far as FormFu is concerned, a single form doesn't have to represent
>>> just a single database row, but can also represent related rows or
>>> resultsets.
>>>
>>> Where would your validation profile be defined?
>>> DBIx::Class::Validation expects each resultsource class to provide a
>>> validation_profile() method which provides the profile.
>>> Would you want that to be shared between DBIx::Class::Validation and
>>> HTML::FormFu ?
>>>
>>> If you can give an example of how you might expect it all to fit
>>> together, I could probably give a better answer of whether FormFu
>>> would be a good choice for this.
>>>
>>> Cheers,
>>> Carl
>>>
>>>
>>> 2009/10/26 Serge Zaschipas <serge at uacoders.com>:
>>> > Hi,
>>> > I use Catalyst + DBIx + FormFu
>>> > I just porting relatively big application with lot of tables to
>>> Catalyst.
>>> > I need make validations on model side (very complex business logic
>>> which
>>> > must be implemented on model level).
>>> > So question is: Is there a native way to use FormFu with
>>> > DBIx::Class::Validation?
>>> > I tried HTML::FormFu::Validator but seems $form->submitted_and_valid()
>>> > validate FormFu constraints only + validate with
>>> > HTML::FormFu::Validator::validate_value()
>>> >
>>> > Best Regards
>>> > Sergiy Zaschipas
>>> >
>>> > _______________________________________________
>>> > HTML-FormFu mailing list
>>> > HTML-FormFu at lists.scsys.co.uk
>>> > http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu
>>> >
>>>
>>> _______________________________________________
>>> HTML-FormFu mailing list
>>> HTML-FormFu at lists.scsys.co.uk
>>> http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/html-formfu/attachments/20091029/6c=
20c26a/attachment.htm


More information about the HTML-FormFu mailing list