views:

2062

answers:

2

Hi, I've been trying to implement a dynamic multi-model form with accepts_nested_attributes_for in my rails application. I've been following Eloy Duran's complex-forms example that shows a 2 level implementation, but I've been trying to expand this to 3 levels. Is there support with accepts_nested_attributes_for for a 3 level form? Can anyone show me how to expand the example app?

I've got the javascript partially working (doesn't always work for some reason) for the 3rd level, but I can't save the 3rd level object(s). The param name it is passing for each attribute is:

 greatgrandparent[grandparent_attributes][0][parent_attributes][0][object_attributes][1249277008434][attribute]

Where greatgrandparent is the object the form is for, grandparent is the first level, parent is the second level, and object is the 3rd level (the one I'm trying to save).

Thanks, I appreciate any pointers.

+11  A: 

I have updated my complex-form-examples to work with Rails 2.3. See the deep branch for an example on deeply nested models.

git clone git://github.com/ryanb/complex-form-examples.git
cd complex-form-examples
git checkout -b deep origin/deep
rake db:migrate
script/server

It is the cleanest solution I've seen so far. If you find any bugs or improvements please add an issue on GitHub.

ryanb
You're a life saver.
William
+1  A: 

First of all thank you Ryan for posting you solution. It does work very well in a two level form, but I've got problems using it in a deeper nested form. Firebug gives me a javascript error if I want to put an add_child_link into another already added partial. There seems to be a escaping bug.

I already tried to avoid escaping the inner partial by passing another option to the link method, but this somehow doesn't work.

def add_child_link(name, f, options)
  fields = new_child_fields(f, options)
  fields = escape_javascript(fields) unless options[:already_escaping] == true
  link_to_function name, %{
        var new_object_id = new Date().getTime();
        var html = jQuery("#{fields}".replace(/#{options[:index]}/g, new_object_id)).hide();
        html.appendTo(jQuery("#{options[:where]}")).show();
      }
end

Any hints on that?

Best regards,

Mike

mike_za