Rails 3 - Multiple model forms within another model
I'm 开发者_Go百科building an application in which i need to add rows to tables from multiple other models.
This is what i have so far (sorry for the sloppy code, first project with ruby/rails). I do realize that I am still missing some key elements to the code for this to function properly, I would just like to make sure I am going about this the right way first. I will also be moving the form to a partial once i get everything working correctly.
# app/views/ticketbuilder/show.html.erb
<ul>
<% @event.sections.each do |s| %>
<li><%= s.name %></li>
<ul>
<% s.locations.each do |l| %>
<li><%= l.name %></li>
<% end %>
</ul>
<% end %>
<li>
<%= form_for([:event, :ticketbuilder], :url => event_ticketbuilder_url) do |s| %>
<%= s.text_field(:section) %> <%= submit_tag("Add Section") %>
<%= s.hidden_field(:event_id, @event.id) %>
<% end %>
</li>
</ul>
# routes.rb
resources :event do
resources :ticketbuilder
end
# ticketbuilder_controller.rb
class TicketbuilderController < ApplicationController
def show
@event = Event.find(params[:event_id])
end
def new
@section = Section.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @event }
end
end
end
# error message
undefined method `model_name' for Symbol:Class
The problem I am having is sending the form to the ticketbuilder controller. What I'm trying to accomplish is to have a list of seating sections with child elements for locations. I would like to be able to add new sections and locations directly on the list page.
Any suggestions would be greatly appreciated.
There are a few things you need to change. First in the show action in TicketbuilderController:
# TicketbuilderController
def show
@event = Event.find(params[:event_id])
@section = Section.new
end
The @section variable is a new Section which will be used in the form_for helper in the view which comes next:
# app/views/ticketbuilder/show.html.erb
<%= form_for @section, :url => event_ticketbuilder_path(@event) do |s| %>
<p><%= s.text_field(:section) %></p>
<p><%= s.submit("Add Section") %></p>
<% end %>
form_for takes an instance of the model you want to create, in this case a Section. The hidden field to store the event_id is not needed because we send the form data to an url which contains the event_id. That url is specified in the :url attribute passed to form_for.
And lastly, the create action in TicketbuilderController:
# TicketbuilderController
def create
@event = Event.new(params[:event_id])
@section = @event.sections.build(params[:section)
if @section.save
@section = Section.new
end
render :action => :show
end
The @event is used to "build" the section. By doing that, the section is associated with the event even though the event_id was not passed in the form. And if the new section was succesfully saved, the @section variable is set to a new instance to prepare for the form_for again.
You should use fields_for
helper.
Look for a good tutorial in railscasts: http://railscasts.com/episodes/73-complex-forms-part-1
精彩评论