Creating a Multi Page Form in Rails | |
Creating a multi-step wizard-like form is pretty difficult in Rails. | |
Especially when trying to apply REST and validations. There are many | |
different approaches to this problem, and the right one depends largely | |
on your application details. Here are four options, and then my final | |
recommendation. Skip to that if you're in a hurry. | |
1. Create the model at the beginning on the first page of the form, and | |
have each successive page update the model. Validations are tricky | |
here, but you can use acts_as_state_machine to keep track of the | |
different states, and add some conditions to validations to trigger | |
them at different states. One downside is that if they stop halfway | |
through you end up with a model which is only partially complete. But | |
then again, this may be an advantage because it saves their progress | |
and they can go back and finish it. | |
2. Have each form pass the previous form values with hidden fields, and | |
then create the model at the very end. Validation is tricky here as | |
well. You can either handle it like the first approach, or do it all at | |
the very end and figure out how to redisplay the invalid fields. | |
3. Use Javascript to make one long form look like a multi-step form. | |
This way, as far as Rails is concerned, it is just like any other form | |
which simplifies a lot. Then, if there's a validation error at the end, | |
just return all of the fields again like normal, and hide the ones that | |
are valid with Javascript/CSS. | |
4. Split the one large model up into multiple models, one for each step | |
in the form. This way you're just creating a model at each step and the | |
validations are handled separately on each one. Usually with this you | |
have one primary model and multiple other models associated to that | |
with has_one or has_many. | |
Option 4 is close to my final recommendation, but not quite. I | |
recommend not using a multi-page forms. They are difficult to | |
implement, and they often result in a poor user experience. The user | |
has questions like "what if I have to stop or my browser crashes? do I | |
have to enter this all over again?". It's also easy to request more | |
information from the user then you actually need. | |
Instead, ask yourself, what is the minimal amount of information | |
required from the user to get started. Have that be a single page form | |
which creates the primary model and then lead to the "show" page for | |
that model. This can contain an overview of the info they submitted | |
along with default values for the rest of the details. This page can | |
have links for editing these other details, which will take them to | |
other forms for creating the other associated models. | |
This way you turn a multi-step form into an interactive application. | |
Not only does this lead to a better user experience, but is usually | |
easier to implement and simplifies the models. This is the REST | |
approach. | |
Ryan Bates | |
http://railscasts.com | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment