Hi,

A clean example that uses HTML::FormFu is:

package MyApp::Controller::Foo;

use Moose;
extends 'Catalyst::Controller::HTML::FormFu';
# or just use parent 'Catalyst::Controller::HTML::FormFu' if you don't use Moose

sub edit : Local FormConfig {
 my ($self, $c, $id) = @_;

 my $form = $c->stash->{form};
 my $foo = $c->model("DB::Foo")->find($id);

 if ($form->submitted_and_valid) {
   $form->model->update($foo);
   $c->flash(notice => "Foo was updated successfully.");
   $c->res->redirect($c->uri_for_action('/foo/index'));
 }
 else {
   $form->model->default_values($foo);
 }
}


sub edit : Local FormConfig {

You can use Path or the chaining dispatch type or something else, not only "Local". If you use the attribute FormConfig, it will search for the form placed by default in
root/forms/foo/edit.conf

If you want to use another specified form, you can use something like:

sub edit : Local FormConfig('path/to/another/form') {


 my $form = $c->stash->{form};

If you use the FormConfig attribute, it will place the form in the stash automaticly so you just need to get it from there.


 my $foo = $c->model("DB::Foo")->find($id);

This uses DBIx::Class result class DB::Foo for getting the $foo record.


if ($form->submitted_and_valid) {

This will be true only if the form past all the validation and constraints.

$form->model->update($foo);

This will update the $foo record in the database. In order to work this way, you need to have defined the database schema in myapp.conf like:

'Controller::HTML::FormFu' => {
 model_stash => {
   schema => 'DB',
 },
},

And in the edit.conf form configuration file (defined below using Config::General) you will need to have defined the resultset like:

<model_config>
resultset Foo
</model_config>


$c->res->redirect($c->uri_for_action('/foo/index'));

$c->uri_for_action is prefered because /foo/index is not a URI but an internal path to the index action from the Foo controller and this code doesn't need to be changed even if the public URI to that action changes.

$form->model->default_values($foo);

This fills the form with the values from $foo record when the form is displayed.

HTH.

--Octavian

----- Original Message ----- From: "E R" <pc88m...@gmail.com>
To: "The elegant MVC web framework" <catalyst@lists.scsys.co.uk>
Sent: Tuesday, September 21, 2010 12:48 AM
Subject: [Catalyst] best practices for handling forms?


Hi,

I am curious what everyone thinks as being the best practices for
handling forms in Catalyst. Are there any Catalyst applications you
have run across which are good examples of how to use Catalyst's
features to handle forms?

To illustrate what I am getting at, below is typical Rails (v2)
controller code which implements updating the attributes of an object:

  def edit
     @book = Book.find(params[:id])
     @subjects = Subject.find(:all)
  end
  def update
     @book = Book.find(params[:id])
     if @book.update_attributes(params[:book])
        flash[:notice] = 'Book successfully updated.'
        redirect_to :action => 'show', :id => @book
     else
        @subjects = Subject.find(:all)
        render :action => 'edit'
     end
  end

In Catalyst, this would be appear something like (and please correct
me if I have made any errors here):

sub edit  :Args(1) {
 my ($self, $c, $id) = @_;
 ... set up $c->stash for template 'edit' ...
# no need to set $c->stash->{template} - will be set from the current action
}

sub update :Args(1) {
 my ($self, $c, $id) = @_;
 ...process form...
 if (form is valid) {
   ...perform updates...
   $c->flash->{notice} = 'Book successfully updated.';
   $c->res->redirect('show', $id);
 } else {
   ... set up $c->stash for 'edit' template ...
   $c->stash->{template} = 'edit';
 }
}

Any comments on this architecture? Is there a better way? My main problems are:

1. The code ... set up $c->stash for 'edit' template ... is duplicated
in both edit and update (which is also true for the Rails code).

2. Having the template name defaulted from the current action is nice,
but that means we have to explicitly set it in the update method. Is
it better to always explicitly set the template name in a controller
method? Then update could perform a $c->detach('edit', $id) or would
you use $c->go('edit', $id)?

Thanks,
ER

_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/


_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/

Reply via email to