[html-formfu] Re: DBIC::Validation::FormFu RFC & Element::Date patch

Jonas Alves jonas.alves at gmail.com
Tue Oct 23 01:28:51 GMT 2007


On 22/10/2007, Carl Franks <fireartist at gmail.com> wrote:
>
> At first, I liked the look of how the REST Action handled things (I'd
> never looked into it before).
> However, thinking about it further, the kind of things I would
> typically do in the GET routine, would usually also be necessary in
> the POST routine if the form's needing to be redisplayed.
> What use cases make it worth the added complexity?
>
> > sub root : Chained('base') PathPart('') Args(0) REST {}
> >
> > # Show the Form to create a new entry
> > sub root_GET {
> >     my ( $self, $c ) =3D @_;
> >     $c->stash(form =3D> $self->model->form);
> > }
> >
> > # Get the data from the form and redisplay with errors if invalid
> > # or redirect to a success page if valid
> > sub root_POST : MyAction('CheckError') {
> >     my ( $self, $c ) =3D @_;
> >     my $new =3D $self->model->create($c->req->params);
> >     $c->redirect($self->create_uri);
> > }
>
> Compared to the above 3 routines, I think I still prefer:
>
> sub foo : Local : FormConfig {
>     my ( $self, $c ) =3D @_;
>
>     if ( $self->stash->{form}->submitted_and_valid ) {
>         $self->model->new->populate_from_formfu( $c->stash->{form} );
>         $c->response->redirect($c->uri_for('done'));
>     }
> }


You don't have to use the REST dispatching if you don't like it. You can
have an equivalent code:

sub foo : MyAction('CheckError') {
    my ( $self, $c ) =3D @_;
    if ( $self->stash->{form}->submitted_and_valid ) {
        $self->model->create($c->req->params);
        $c->redirect($self->create_uri);
    }
}

Just have to change your CheckError action to this:

sub execute {
    my $self =3D shift;
    my ($controller, $c ) =3D @_;

    $c->stash(form =3D> $self->model->form);
    eval {
        $self->next::method( @_ );
    };
    if (blessed $@ && $@->isa('HTML::FormFu')) {
        my $form =3D $@;
        $c->error(0);
        $c->stash(form =3D> $form);
        my $errors =3D { map { $_->name =3D> $_->message } @{$form->get_err=
ors}
};
        $c->res->status('400'); # Bad Request
        $c->stash(rest =3D> $errors);
    }
}


Would you mind posting the code you have so far for DBIC::Validation::FormFu
> ?
>
> Carl
>
>

Yes, sure. Here it is:


package SMS::DBIC::Validation::FormFu;
use strict;
use warnings;
our $VERSION =3D '0.01';
use Data::Dumper;
use Clone qw/clone/;
use Carp;

BEGIN {
    use base qw/DBIx::Class::Validation/;
    use DBIx::Class::HTML::FormFu;
    use HTML::FormFu;
    use Path::Class::Dir;
    use Carp qw/croak/;

    __PACKAGE__->mk_group_accessors('inherited', qw/
        validation_formfu_args
        validation_formfu_config
        validation_formfu_dir
        _form
    /);
};

__PACKAGE__->validation_formfu_args({
    query_type =3D> 'Catalyst',
    render_class_args =3D> {
        ENCODING =3D> 'UTF-8',
        INCLUDE_PATH =3D> '/Users/jgda/Devel/SMS/root/formfu',
    },
});

sub validation {
    my ($self, %args) =3D @_;
    $self->validation_forfu_args($args{forfu_args}) if exists
$args{forfu_args};
    $self->validation_formfu_config($args{formfu_config}) if exists
$args{formfu_config};
    $self->validation_formfu_dir($args{formfu_dir}) if exists
$args{formfu_dir};
    $self->next::method(%args);
};

sub form {
    my $self =3D shift;
    my $form =3D $self->_form || $self->set_form;
    warn "SELF: @{[ref $self]}\n";
    return ref $self
      ? do {
          $form->stash->{dbic_instance} =3D $self;
          DBIx::Class::HTML::FormFu::fill_formfu_values($self, $form);
        }
      : $form;
}

sub set_form {
    warn "Estou no set_form\n";
    my ($self, $source) =3D @_;
    my $form =3D HTML::FormFu->new($self->validation_formfu_args);
    $source ||=3D $self->result_source;
    my $config =3D $self->validation_formfu_config || do {
        my $dir =3D $self->validation_formfu_dir;
        my $file =3D lc $source->from . '.yml';
        $dir ? Path::Class::Dir->new($dir)->file($file) : undef;
    } || return;
    if (ref $config eq 'HASH') {
        $form->populate($config);
    }
    else {
        return unless -r $config;
        $form->load_config_file($config);
    }
    $form->stash->{schema} =3D $source->schema;
    $form->stash->{resultset} =3D $source->name;
    $self->_form($form);
    return $form;
}

sub new {
    my ($class, $attrs, @rest) =3D @_;
    my $source =3D $attrs->{'-result_source'};
    $class->throw_exception("No result_source set on this object; can't
insert")
      unless $source;

    my $form =3D $class->set_form($source) or
      return $class->next::method($attrs, @rest);

    my %form_fields;
    my $attrs_copy =3D clone $attrs;
    if ($attrs) {
        $class->throw_exception("attrs must be a hashref")
          unless ref($attrs) eq 'HASH';
        for my $key (keys %$attrs_copy) {
            $form_fields{$key} =3D delete $attrs_copy->{$key}
              if $form->get_field({ name =3D> $key })
                 && !$source->has_column($key)
                 && !$source->has_relationship($key);
        }
    }

    delete $attrs->{'-result_source'};
    delete $attrs->{'-source_handle'};

    $class->validate($attrs) if %$attrs && $class->validation_auto;

    my $self =3D $class->next::method($attrs_copy);
    $self->{_formfu_extra_fields} =3D \%form_fields if %form_fields;

    return $self;
}

sub validate {
    my $self =3D shift;
    my $form =3D $self->form or return;
    my $data =3D shift || {
        $self->get_inflated_columns,
        %{$self->{_formfu_extra_fields} || {}},
    };

    #warn 'Data: ' . Dumper $data;
    $form->process($data);

    if ($form->has_errors) {
        croak $form;
    } else {
        return $form unless ref $self;
        if ($self->validation_filter) {
            $self->store_inflated_column($_ =3D> $form->param($_))
              for keys %{{$self->get_inflated_columns}};
        }
        return $form;
    }
}

1;
__END__

Cheers,
-- =

Jonas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/html-formfu/attachments/20071023/df=
ee243a/attachment-0001.htm


More information about the HTML-FormFu mailing list