开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜