Использование awesome_nested_set для динамического добавления дополнительных детей - PullRequest
3 голосов
/ 23 июня 2011

У меня есть вложенная модель под названием категории, и я создал вложенную форму, чтобы разрешить создание категории и подкатегорий в одной форме.

Это прекрасно работает, если вы предварительно создали детей в своемновый метод, подобный так:

class CategoriesController < InheritedResources::Base
  def new
    @category = Category.new
    @category.children.build
  end
end

Проблема начинает возникать, когда вы хотите динамически добавлять новых дочерних элементов в форму, используя AJAX.

Вот моя форма:

%table
    = form_for @category do |f|
        %tr
            %td= f.label :name
            %td= f.text_field :name

        %tr
            %td(colspan=2)
                %b Sub categories

        - @category.children.each do |sub|
            = f.fields_for :children, sub do |child|
                = render "child_fields", :f => child
        %tr
            %td= link_to_add_fields "Add sub category", f, :children
        %tr
            %td= f.submit 'Save'

Вот мой вспомогательный метод для link_to_add_fields (согласно Ryans Railscast):

module ApplicationHelper
  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(:partial => association.to_s.singularize + "_fields", :locals => { :f => builder})
    end
    link_to_function(name, "add_fields(this, '#{association}', '#{escape_javascript(fields)}')")
  end  
end

А вот Javascript, который более

function add_fields(link, association, content) {
    // Generate new unique index, so base this off the current time.
    var new_id = new Date().getTime();
    var regexp = new RegExp("new_" + association, "g")

    // Replace new_association with the current time.    
    $(link).closest("tr").before(content.replace(regexp, new_id));
}

Я заметил, что на предварительно собранномнижестоящие выводимые данные выглядят так:

<input type="text" size="30" name="category[children_attributes][0][name]" id="category_children_attributes_0_name">

Где в качестве полей, сгенерированных AJAX:

<input type="text" size="30" name="category[children_attributes][1308801890744][name]" id="category_children_attributes_1308801890744_name">

Это выглядит правильно, но когда я щелкаю, создаю только предварительно построенные потомкисохранены.

Update1 Если я добавлю строку отладчика в свой def и создаю params, я вижу только свою предварительно созданную категорию, а не дополнительную, которую я динамически добавил.

(rdb:4) params
{"utf8"=>"✓", "authenticity_token"=>"iwq1Vx3jOZZsjd79Nj+qKNXxOwWP40c8XDFS8ooGMdg=", "category"=>{"name"=>"1", "children_attributes"=>{"0"=>{"name"=>"2"}}}, "commit"=>"Save", "action"=>"create", "controller"=>"categories"}

1 Ответ

1 голос
/ 28 июня 2011

Это результат того, что браузеры (по крайней мере, Firefox) ведут себя странно, когда форма находится внутри таблицы. Самое простое / быстрое решение - поместить таблицу в форму. Это изменение в одну строку для вашего файла views / category / new.haml:

= form_for @category do |f|
    %table
        %tr

Как я отлаживал это, если это помогает: Я сначала проверил request.raw_post; параметров не было, что означало, что рельсы никогда не видели правильный запрос. Это указывало на проблему рендеринга в браузере.

Я смог отладить проблему с помощью firebug, заметив, что форма неуклюже закрывалась при рендеринге вашего оригинального haml. Перемещение формы из таблицы, казалось, исправило это в firefox.

Я бы предложил придерживаться div, в основном потому, что это позволяет избежать многих странных проблем с браузером.

...