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| %>

Name :<%= ferm.name %>

<% form_for(ferm, @kinetic) do |f| %>

<Something<%= f.text_field :something %>

<% 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>
Tank <%=h kinetic.ferm.tank %> Blend <%=h kinetic.ferm.blend_number %> Brix <%= text_field(:kinetic, :brix, :name => "kinetic[][brix]") %> Temp <%= text_field(:kinetic, :temp, :name => "kinetic[][temp]") %> <%= hidden_field_tag(:kinetic, :ferm_id, :name => "kinetic[] [ferm_id]", :value => kinetic.ferm.id) %>

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

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

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.