Help with nested models and fields_for

Marnen Laibow-Koser
Sat, 20 Dec 2008 02:51:11 -0000

Hi folks.

I''m trying to do stuff with models nested one layer deeper than
I''ve
done in the past...and it''s just not working properly.  Here''s
the
situation:

* I have three models involved here: Recipe, IngredientLine, and
Ingredient (it''s a cookbook application).

class Recipe < ActiveRecord::Base
  has_many :ingredient_lines
  has_many :ingredients, :through => :ingredient_lines
end

class IngredientLine < ActiveRecord::Base
  belongs_to :ingredient
  belongs_to :recipe
end

class Ingredient < ActiveRecord::Base
  has_many :ingredient_lines
  has_many :recipes, :through => :ingredient_lines
end

* I''m trying to develop a form which edits a Recipe along with its
associated IngredientLines and Ingredients. Right now, I''ve been
working with this sort of thing (it''s a Facebook app, hence the .fbml
extension, and I''m only doing relevant excerpts so as not to take up
too much space here):

--- recipe/views/new.fbml.haml ---

- form_for(@current_object) do |f|
  = f.text_field :name
  = render :partial => ''ingredient'', :locals => {:f
=> f}
  = f.text_area :instructions

--- recipe/views/_ingredient.fbml.haml ---
- f.fields_for :ingredient_lines, :index => nil do |ff|
  %td= ff.text_field :quantity, :size => 3, :maxlength => 3, :id =>
nil
  %td= ff.text_field :unit, :id => nil
  - ff.fields_for :ingredient do |i|
    %td= i.text_field :name, :id => nil

* I''ve tried this with fields_for instead of f.fields_for as well.

* There''s some JavaScript to produce multiple copies of the partial
for multiple ingredient, but I''m omitting that since it''s not
relevant
here.

* The HTML/FBML output for this is as expected:

<form action="/recipes" class="new_recipe"
id="recipe_1015"
method="post">
  <input id="recipe_name" name="recipe[name]"
size="30" type="text" />
  <input id="recipe_ingredient_lines__quantity"
maxlength="3"
name="recipe[ingredient_lines][][quantity]" size="3"
type="text" />
  <input id="recipe_ingredient_lines__unit" name="recipe
[ingredient_lines][][unit]" size="30" type="text" />
  <input id="recipe_ingredient_lines__ingredient_name"
name="recipe
[ingredient_lines][][ingredient][name]" size="30"
type="text" />
  <textarea cols="40" id="recipe_instructions"
name="recipe
[instructions]" rows="20">


So far so good.  But here''s the problem: *submissions don''t
work quite
properly*.  When I fill out the form and submit it, I get params
entries like
"recipe"=>{"name"=>"Recipe",
"ingredient_lines"=>[{"quantity"=>"1",
"unit"=>"cup", "ingredient"=>{}}],
"instructions"=>"Preheat oven to
350°..."}. Note that ingredient_lines[0].ingredient.name is missing,
even if I enter text in the corresponding form field -- in other
words, what I should be seeing is something like "recipe"=>
{"name"=>"Recipe",
"ingredient_lines"=>[{"quantity"=>"1",
"unit"=>"cup",
"ingredient"=>{"name" => "flour"}}],
"instructions"=>"Preheat oven to 350°..."}.  What am I
doing wrong?

Any suggestions would be helpful.  Thanks in advance!