Problems with accepts_nested_attributes_for

Hopefully someone can help. I have the following models

class Parent < ActiveRecord::Base

schema id int, name string

has_many :children
accepts_nested_attributes_for :children
end

class Child < ActiveRecord::Base

schema id int, name string, parent_id int

belongs_to :parent
end

… the following view …

New parent

<% form_for :parent, :url => { :action => :create } do |p| %>
<%= p.text_field :name %>


<% p.fields_for :children do |c| %>
<%= c.text_field :name %>
<% end %>

<%= p.submit ‘Create’ %>

<% end %>

… and a scaffold built parents_controller …

GET /parents/new

GET /parents/new.xml

def new
@parent = Parent.new

respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @parent }
end

end

POST /parents

POST /parents.xml

def create
@parent = Parent.new(params[:parent])

respond_to do |format|
  if @parent.save
    flash[:notice] = 'Parent was successfully created.'
    format.html { redirect_to(@parent) }
    format.xml  { render :xml => @parent, :status => :created, 

:location
=> @parent }
else
format.html { render :action => “new” }
format.xml { render :xml => @parent.errors, :status =>
:unprocessable_entity }
end
end
end

I’m getting this error …
ActiveRecord::AssociationTypeMismatch in ParentsController#create

Child(#-608967938) expected, got Array(#-605071598)

Paramters …
{“parent”=>{“name”=>“Ants”,
“children”=>{“name”=>“Pants”}},
“commit”=>“Create”,
“authenticity_token”=>“x4BoHI06Asp6QumOwFkccthv+no7ychn57tqOl7q9Ig=”}

I’ve tried inserting the same details via the console and it worked but
I
provided a list ot children_attributes …

params = { :parent => { :name => ‘Ants’, :children_attributes => [ {
:name
=> ‘Pants’ } ] } }
p = Parent.create(params[:parent])

and that works fine

So, how do I get :children_attributes => [ { :name => ‘Pants’ } ] } to
be
passed in the params to the controller from the form_for / fields_for in
the
view?

Plus, I really need to get this to work with another model relationship
that
such as …

class Account < ActiveRecord::Base
has_many :memberships
has_many :members, :through => :memberships

accepts_nested_attributes_for :members
end

class Member < ActiveRecord::Base
has_many :memberships
has_many :accounts, :through => :memberships
end

class Membership < ActiveRecord::Base
belongs_to :member
belongs_to :account
end

Is there anything special I need to fdo for the :through ??/

Thank you for any light you can throw on this

-Ants

100% naturally selected. 0% designed.

Hi Anthony,

It looks like your form_for line in your view is wrong… try this:
<% form_for(@parent) do |p| %>

…instead of this:
<% form_for :parent, :url => { :action => :create } do |p| %>

For some reason the way you called form_for isn’t compatible with the
nested attributes feature, and so your form’s HTML didn’t contain the
proper name for the child field name=“parent[children_attributes][0]
[name]”. Also, I added a line to your controller to create a single
new child when creating a new parent form; otherwise the child name
field won’t appear:

def new
@parent = Parent.new
@parent.children.build

respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @parent }
end

end

It should work exactly the same way with the has_many, :through
association. Hope this helps!

  • pat

Cool. Thanks, Pat.

Have just implemented that and it works fine … even with :through.

Nice.

-Ants

2009/7/22 Pat [email protected]

nested attributes feature, and so your form’s HTML didn’t contain the
format.html # new.html.erb
On Jul 21, 3:10 pm, Anthony G. [email protected] wrote:

belongs_to :parent
<%= c.text_field :name %>
def new
def create
format.html { render :action => “new” }

:name

Is there anything special I need to fdo for the :through ??/

Thank you for any light you can throw on this

-Ants

100% naturally selected. 0% designed.


100% naturally selected. 0% designed.