This project is archived and is in readonly mode.

#3007 ✓invalid
jamesw

accepts_nested_attributes causes errors eith has_many :through relationships

Reported by jamesw | August 8th, 2009 @ 05:19 PM

Cannot modify association 'Grandparent#children' because the source reflection class 'Child' is associated to 'Parent' via :has_many.
This affects versions 2.3.2 and 2.3.3 I can not speak for any other versions as I have not tried it on them.

This exception is raised on has_many :through relationships where the accepts nested attributes is on the grandchild

Steps to re-create the problem

scaffold child name:string, parent_id:integer
scaffold parent name:string, grandparent_id:integer
scaffold grandparent name:string

Obviously run the migrations.
Change the models to look like this

class Child < ActiveRecord::Base
belongs_to :parent end

class Parent < ActiveRecord::Base
has_many :children belongs_to :grand_parent

accepts_nested_attributes_for :children

end

class Grandparent < ActiveRecord::Base
has_many :parents has_many :children,

:through => :parents

accepts_nested_attributes_for :children end

Change the grandparent edit.html.erb to look like this

Editing grandparent

<% form_for(@grandparent) do |f| %>
<%= f.error_messages %>

<%= render :partial => 'form', :locals => {:f => f} %>

<%= f.submit 'Update' %>
<% end %>

<%= link_to 'Show', @grandparent %> |
<%= link_to 'Back', grandparents_path %>

Create the partial '_from.html.erb'

<%= f.label :name %><br />
<%= f.text_field :name %>

You might also need the _child_list.html.erb file in the grandparents view folder
<%= child_list.house %>, <%=link_to 'Edit'%>

Now create a _child_form.html.erb partial in the grandparents view folder

<%= f.label :name %><br />
<%= f.text_field :name %>

<%= link_to_function "Show/Hide children", {:id => "toggle_children"}%> <!--ignore this, It is not needed to reproduce the problem and is there to show/hide a list of children using jQuery code-->

<%= add_child_link(f) %>

In application_helper.rb add these 2 methods
module ApplicationHelper
def link_to_toggle_child_list(div_to_toggle, link_text)

link_to_function link_text do |page|
  page << "jQuery('#{div_to_toggle}).toggle('slow')"
end

end

def add_child_link(form_builder)

link_to_function 'New child' do |page|
  form_builder.fields_for :children,
                          Child.new,
                          :child_index => 'NEW_RECORD' do |f|
    html = render(:partial => 'child_form', :locals => { :f => f })
    page << "jQuery('#maintenance_form').replaceWith('#{escape_javascript(html)}'.replace(/NEW_RECORD/g, new Date().getTime()))"
  end
end

end

end

Create a new grandparent record. and give it a name of g1
Create a new parent record and give it a name of p1 and set the granparent_id to the value of the index for the grandparent record you just created

Once you have this then use the edit view from the grandparent index view for "g1".
Click the New child link and in the form that appears enter a name then click the update button.
You will get the error reported above.

To prove that the code should work

Copy the partials from.html.erb child_form.html.erb and _child_list.html.erb to the parents view folder.

Change the edit.html.erb to render the _form partial in the parents view folder

Then use the app to edit the parent "p1", add a child using the same link as before It will work and you will a new child record associated weith the parent record.

Please let me knopw if you need any further info and if you can think of an immediate work around for this I would love to hear it as this is rather an urgent problem for me right now

Thanks

James

Comments and changes to this ticket

  • jamesw

    jamesw August 11th, 2009 @ 01:50 PM

    Since posting this ticket I have done further investigations and it looks like this problem is related to geting the fields_for declaration right but no matter what I try I can not make this work with a has_many :through association.

    I realise that what I posted above is not quite right as I need to tell the params hash what parent to add the child to but including the parent in the params hash either results in a new parent being created using the child information or one of various errors depending on how I set the fields_for.

    The closest I have got to a solution has been posted in the rails forum here
    http://railsforum.com/viewtopic.php?id=33642

    I am going to abandon use if accepts_nested_attributes for the time being as this is mission critical and has held me up for far too long but if anyone is able to find a solution then please let me know (I'm watching this ticket).

    Thanks

    James

  • Manfred Stienstra

    Manfred Stienstra August 11th, 2009 @ 02:09 PM

    • State changed from “new” to “incomplete”

    The exception you're getting has to do with the fact that a has_many :through relation can't inflect what it needs to change in order to make this happen. If you can find a way to work around it and provide a patch we will happily accept it. I'm closing this ticket until someone provides a patch.

  • jamesw

    jamesw August 11th, 2009 @ 02:48 PM

    Thank you,
    I am getting VERY VERY close to a solution.
    I have actually just managed to get a child record to save, however it was saved against the wrong parent.
    If I can find out the solution I'll post back here.

  • Neeraj Singh

    Neeraj Singh July 15th, 2010 @ 03:19 AM

    • State changed from “incomplete” to “invalid”
    • Importance changed from “” to “”

    Marking the ticket as invalid for now. If there is a patch and further interest in the ticket it can be reopened.

  • bingbing

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Referenced by

Pages