views:

75

answers:

3

I'm fairly new to Rails.

What is the best way to design/structure a multi-page form in Rails? I would like the form to create a new record in the database immediately when the first page of the form is submitted, and for each subsequent page of the form to update that record in the database.

The reason I want the record created immediately after the first page is submitted is so that there can be the notion of an unfinished record that the user comes back to later to finish.

Once created, I would like to allow the user to edit any part of the model by going directly to that section.

I know enough Rails where if you guide me with the best way to structure this conceptually, I should be able to figure out the code myself.

Thank you.

+1  A: 

Ryan Bates explains this in one of his Railscasts => MultiSteps Forms

jpemberthy
Thank you for your reply.I actually stumbled upon this Railscast. Ryan's method is different than what I'm looking for. Ryan writes to the database at the very last step. I would like to write to the database immediately after the first step such that an unfinished record remains in the database if the user abandons the form after the first step.
Sanjay
+1  A: 

I have a multi-step signup process that works this way. I create the record the first time and then the other steps are edit/updates on that record. I use multiple controllers for this; it is a much cleaner approach than trying to cram all the logic into one controller action (although you could use multiple actions from the same controller and it would work just as well, but don't forget to create routes for your custom actions). This approach makes validation more difficult for the data added in steps after the first, but you can always add your own errors by calling errors.add on your model, essentially rolling your own validations. You can also write logic in your sessions controller to direct the user back to the same step in the multi-step form if they return later and have not completed it.

John Glass
Thanks, John. I actually ended up doing something very similar to what you describe.
Sanjay
A: 

I've inherited a 'multi-page' form along those lines - but it was built for Rails 2.2 and I'm only just adapting the approach for Rails 3.

Essentially we used a tabbed layout with the entire form in one view - although this approach was heavily weighted towards one controller in Rails 2.2 I think it can be broken down better.

The layout meant that each section of the form could be accessed by the tabs - but each tabbed section also had a link_to action to the next section, at the bottom of that section (section A -> section B, for example) that saved the entire form each time you moved onto a new section - I've heavily edited the view just to give an idea but if it's a new form it will only reveal each section after the submit button for each section has been pressed.

    <ul id="tabs">
    <li><a href="#SectionA">Section A</a></li>
    <li><a href="#SectionB">Section B</a></li>
    <li><a href="#SectionC">Section C</a></li>
    <li><a href="#SectionD">Section D</a></li>
    <li><a href="#SectionE">Section E</a></li>
    <li><a href="#SectionF">Section F</a></li>
    <li><a href="#SectionG">Section G</a></li>
    <li><a href="#SectionH">Section H</a></li>
    <li><a href="#SectionI">Section I</a></li>
    <li><a href="#SectionJ">Section J</a></li>
</ul>

<%=hidden_field_tag 'active_fabtabulous_tab'%>
<% form_for(@detail) do |f| %> 
<%= f.error_messages %>

 <div class="panel"  id="SectionA">
        <b><u>Section A: Questionnaire Details</u></b>
        <br></br>
        <table>
            <tr>
                <td><div id="field_name">Questionnaire received on (dd/mm/yyyy):</div></td>
                <td><%= date_select("questionnaire", :received_on, :order=>[:day,:month,:year],:use_month_numbers=>true,:start_year=>Date.today.year,:end_year=>2008,:include_blank => true) %></td>
            </tr>
            <tr>
                <td><div id="field_name">Interviewer name:</div></td>
                <td><%=text_field("questionnaire",:intervieweename)%></td>
            </tr>   

        </table><!-- end questionnaire div -->

        <%= f.submit "SectionB" , :class => "questButton" %>

    </div>

<!--- Page 2 --->


    <div class="panel"  id="SectionB">
        <b><u>Section B: Case Classification</u></b>
        <br></br>

        <% fields_for :patient, @patient do |p| %>

            <table>
                <tr>
                    <td class="sectionA_is_this_case"><div id="field_name">Epidemiology definition:</div></td>
                    <td><%= @patient.epidef %>
                    </td>
                </tr>
            </table>
        <% end %>


        <table>
            <tr>
            <% fields_for :patient, @patient do |p| %>

                <td><div id="field_name">Asymptomatic:</div></td>
                <td><% if @patient.asymptomatic %>Yes<% else %>No<% end %></td>
            <% end %>
            <tr>
            <tr>
                <td><div id="field_name">Investigation is:</div></td>
                <td><%=select("detail", "invstatus", INVESTIGATION_IS)%></td>
            </tr>
            <tr>
                <td><div id="field_name">Outbreak keyword or number:</div></td>
                <td><%= f.text_field :outbreakid ,:cols => 40, :rows => 1 %></td>
            </tr>

        </table>

        </div>
        <%= f.submit "SectionC" , :class => "questButton" %>

    </div>
Pasted
Just to add a tabbed form helper that I'll be trying - http://github.com/LRDesign/logical_tabs
Pasted