问题
I'm trying to create a multi-page form that uses multiple models. I have an applicant and this applicant has more than one address (one to many relationship).
I would like the first page to contain information about the applicant, and then the page after that to have the form for the address(es)
This is what I have at the moment:
applicant.rb
has_many :addresses, :dependent => :destroy
accepts_nested_attributes_for :addresses
address.rb
belongs_to :applicant
applicants_controller.rb:
def new
session[:applicant_params] ||= {}
@applicant = Applicant.new(session[:applicant_params])
2.times do
@addresses=@applicant.addresses.build
end
session[:address_params] = @addresses.attributes
end
def create
session[:applicant_params].deep_merge!(params[:applicant]) if params[:applicant]
session[:address_params] ||= params[:address]
@applicant = Applicant.new( session[:applicant_params] )
@applicant.addresses.new(session[:address_params])
if params[:forward_button] or params[:back_button]
@applicant.current_step = session[:applicant_step]
if params[:back_button]
@applicant.previous_step
else
@applicant.next_step
end
session[:applicant_step]=@applicant.current_step
render "new"
else
.....
In the new view:
<%= form_for @applicant do |f| %>
<%= render "#{@applicant.current_step}_step", :f => f %>
<p><%= f.submit "Continue", :name => "forward_button" unless @applicant.last_step? %> </p>
<p><%= f.submit "Back", :name => "back_button" unless @applicant.first_step? %></p>
<% end %>
@applicant.current_step will be either address_step or applicant_step, and these are below:
_applicant_step.html.erb
<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name ,:width=>'10px', :size=>"20", :maxlength=>"20" %>
</div>
<div class="field">
<%= f.label :middle_name %><br />
<%= f.text_field :middle_name %>
</div>
....
_address_step.html.erb
<%= f.fields_for :addresses do |u| %>
<div class="field">
<%= u.label :address %><br />
<%= u.text_area :address , :cols=> 20, :rows=>5%>
</div>
<div class="field">
<%= u.label :telephone, "Telephone Number" %><br />
<%= u.text_field :telephone %>
</div>
...
And that's it. Now the problem I have is as follows, I want to save the address information as well as the applicant information. And I thought just by saying: @applicant.addresses.new then they will be included in the session information of the applicant, but they weren't (when I got the the address page, there were no fields!). So I created a new session variable to hold the address information. But I have a problem. Everytime I go from one page to the other (in the create action) a new address field (with all its attributes) is created and added to the form. So first I have one address, then I have 2 and so on. Am I going about this the wrong way? How can I have a multi-page form, with multiple models (that are related), and when going from one page to the next the data is not erased.. Until I eventually reach the last page where I could submit (and save) all the models..
I would be grateful if anyone could help.. Thank you.
回答1:
You can certainly get this working, but (depending on the number of steps you need), it could get pretty convoluted.
Have you considered using a single new
and create
request on the server side, and using Javascript to break up the form into multiple steps on the client side? It seems like this could be a lot simpler. Your Rails application will behave more like a standard REST application, and you can break this up however you see fit on the client side.
I have not used it myself, but a jQuery plugin such as this one should do the trick: http://thecodemine.org/
来源:https://stackoverflow.com/questions/9445893/multi-page-multi-model-form-in-rails