Create multiple new objects in one page

I'm trying to make a view with one form for each instance of a model (ferms) in which a user can update some attributes (in this case I'm calling them kinetics)

Ferm   has_many :kinetics

Kinetic   belongs_to :ferm

In my KineticsController I have before_filter :get_ferms

private   def get_ferms     @ferms = Ferms.find(:all)   end In my new action in the KineticsController I have

@kinetic = Kinetic.new

And that's where I get stuck...

Here is what I have in the views/kinetics/new.html.erb:

<% @ferms.each do |ferm| %>   <p><b>Name :</b><%= ferm.name %><p>   <% form_for(ferm, @kinetic) do |f| %>      <p><b><Something</b><%= f.text_field :something %></p>   <% end %> <% end %>

But it's broken..... Any ideas on what to change/do differently to create the page with multiple forms?? Thanks for any help,

SH

watch the railscasts on complex forms:

Part 1 #73 Complex Forms Part 1 - RailsCasts Part 2 #74 Complex Forms Part 2 - RailsCasts Part 3 #75 Complex Forms Part 3 - RailsCasts

I think I'm close to figuring it out... below are the relevant app details, any suggestions are greatly appreciated.

Models:

class Ferm < AR::Base   has_many :kinetics, :dependent => :destroy end

class Kinetic < AR::Base   belongs_to :ferm end

Controllers

class KineticsController < AC   def new       @kinetics =       @ferms = Ferm.find(:all)       for ferm in @ferms          kinetic = ferm.kinetics.build(params[:kinetic])          @kinetics << kinetic       end    end

   def create      @kinetics = params[:kinetic]      for kinetic in @kinetics         new_kinetic = Kinetic.new(params[:kinetic])         new_kinetic.save      end      redirect_to :controller => 'ferms', :action => 'index'    end

View

  Kinetics/new.html.erb

    <% form_tag(:action => 'create') do -%>   <%= render :partial => 'kinetic', :collection => @kinetics %>   <%= submit_tag 'Enter Brix & Temp' %>     <% end -%>

  Kinetics/_kinetic.html.erb

    <table>   <tr>     <td>Tank</td>     <td><%=h kinetic.ferm.tank %></td>     <td>Blend</td>     <td><%=h kinetic.ferm.blend_number %></td>   </tr>   <tr>     <td>Brix</td>     <td><%= text_field(:kinetic, :brix, :name => "kinetic[brix]") %></

    <td>Temp</td>     <td><%= text_field(:kinetic, :temp, :name => "kinetic[temp]") %></

    <%= hidden_field_tag(:kinetic, :ferm_id, :name => "kinetic [ferm_id]", :value => kinetic.ferm.id) %>   </tr>     </table>

..........

What this gives me in the params hash is: parameters: {"commit"=>"Enter Brix & Temp", "kinetic"=[{"ferm_id"=>[1], "brix"=>[25], "temp"=>[70]},{"ferm_id"=>[2], "brix"=>[28], "temp"=>[80]}] and I get the error: NoMethodError in KineticsController#create ... undefined method `stringify_keys!' for #<Array:0x198b1dc>.

I understand that stringify_keys! is expecting a hash and getting an array and that's why it's complaining... am I instantiating the @kinetics variable incorrectly in KineticsController#new to handle this array? Should I reconfigure the form to submit a hash of the kinetics (like: {"1"=>[{"ferm_id"=>"1", "brix"=>"25", "temp"=>"70"}]})?

Any help is appreciated.... thanks in advance.

SH

What this gives me in the params hash is: parameters: {"commit"=>"Enter Brix & Temp", "kinetic"=[{"ferm_id"=>[1], "brix"=>[25], "temp"=>[70]},{"ferm_id"=>[2], "brix"=>[28], "temp"=>[80]}] and I get the error: NoMethodError in KineticsController#create ... undefined method `stringify_keys!' for #<Array:0x198b1dc>.

Oops typo above: the array looks like :

"kinetic"=[{"ferm_id"=>"1", "brix"=>"25", "temp"=>"70"}, {"ferm_id"=>"2", "brix"=>"28", "temp"=>"80"}]

without square brackets around the values.

figured it out... my problem was in the new action in the KineticsController. Here is what has worked:

def new   @kinetics = params[:kinetic]   @kinetics.each do |k|       new_kinetic = Kinetic.new       new_kinetic.brix = k["brix"]       new_kinetic.temp = k["temp"]       new_kinetic.ferm_id = k["ferm_id"]       new_kinetic.save     end   end

I'm sure there are several better ways to do this, please chime in if anyone wants to share an improvement to this method.

SH