Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi page forms in Rails

I'm having a quite complex model with many fields, has_many associations, images added by image_column etc...

The New object will be added by a multi page form (8 steps) - How should I accomplish validation and propagation between those steps?

I think validation_group could be useful for defining validations for each step, what about overall design?

like image 818
Tomasz Tybulewicz Avatar asked Oct 14 '08 10:10

Tomasz Tybulewicz


2 Answers

For overall design, you might want to look into the concept of a Presenter layer (Jay Fields defines it in his blog entry Rails: Presenter Pattern) as a way to keep your controllers thin and views stupid when dealing with complex/multiple models.

like image 89
Michael Sepcot Avatar answered Oct 07 '22 07:10

Michael Sepcot


You could have a series of methods, e.g. step_1, step_2, and each one checks to see that the necessary data from the previous step was submitted. You could store data in the session so that, for example, step 3 would still have access to all the data collected and parsed in step 1. In the final step, put all the data that you've stored in the session plus the data from the penultimate step to use, and create a new row in the database or whatever you're gathering the data for. If a user messes up a step, redirect them to the previous step and fill out the form for them with the data they did fill out; e.g. if the user messes up step 2 and submits the form leading to step 3, catch the problem in your step_3 method, redirect the user to the step_2 method, and be sure the form elements in step 2 are pre-filled.

If you don't want to store data in the session as you go, you could create a new database row after the user has submitted step 1 and just update the fields in that row as you gather new data in each successive step. You could have some flag for 'complete' on the row, initially setting it to 0 and then setting it to 1 after the user has successfully completed all the steps.

You could also allow users to go to previous steps (e.g. let the user return to step 3 when he is on step 5).

Say your first step has a form with fields 'name' and 'email'. In your step_2 method, you should verify that params[:name] and params[:email] were passed and are valid. Store those in the session or a database row, however you chose. Then in step 2, you have a form with fields 'age' and 'gender'. In your step_3 method, you should verify that params[:age] and params[:gender] were passed and are valid, and you also need to ensure that the user has completed step 1, to prevent a user from entering the URL to access step 3 directly. And so on.

like image 24
Sarah Vessels Avatar answered Oct 07 '22 06:10

Sarah Vessels