views:

24

answers:

0

I would like to get full nested (multiple levels) forms working with awesome_nested_set. Currently I've got one level working by adapting Ryans example from his Railscast: http://railscasts.com/episodes/197-nested-model-form-part-2

In my test app I have categories and I would like to go three levels deep eg: Categories -- Sub Category ---- Sub sub Category

Here is my code which works for adding Categories and Sub categories in one form:

category.rb (model)

class Category < ActiveRecord::Base
  acts_as_nested_set
  accepts_nested_attributes_for :children, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
  named_scope :all_nested, :order => "lft"
end

categories_controller.rb (make_resources just simplifies the controller) class CategoriesController < ApplicationController make_resourceful do actions :all

    before :index do
      @categories = Category.all_nested      
    end

    before :new do
      3.times { @category.children.build }
    end
  end
end

_form.html.haml - form_for(@category) do |f| = f.error_messages %p = f.label :name = f.text_field :name

 - f.fields_for :children do |builder|
  = render "child_fields", :f => builder

 = link_to_add_fields "Add Sub Category", f, :children
 %p
  = f.submit 

_child_fields.html.haml %p#fields = f.label :name, "Sub Category Name:" = f.text_field :name = link_to_remove_fields "remove", f

application_helper.rb module ApplicationHelper def link_to_remove_fields(name,f) f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)") end

  def link_to_add_fields(name,f,association)
    new_object = f.object.class.reflect_on_association(association).klass.new
    fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
      render(association.to_s.singularize + "_fields", :f => builder)
    end
    link_to_function(name, h("add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")"))
  end
end

application.js (jquery) function remove_fields(link){ $(link).prev("input[type=hidden]").val("1"); $(link).closest("#fields").hide(); }

function add_fields(link, association, content){
    var new_id = new Date().getTime(); 
    var regexp = new RegExp("new_" + association, "g")
    $(link).before(content.replace(regexp, new_id));
}

The problem is that in Ryans example he has different names for the associations as they are separate models but in my case it's all referring to the same model as it's nested. I can get away with this for the first level as the children association loads the child_fields partial.

The problem is the third level.

Note: I'm using Rails 2.3.8, jquery 1.4.2, haml and awesome_nested_set