обновление рельсов nested_form - PullRequest
0 голосов
/ 04 марта 2012

я пытаюсь использовать nested_form. все работает нормально, кроме операции удаления ребенка. он работает нормально с добавлением / обновлением. я даже не изменил класс контроллера.

похоже на событие, хотя я удаляю элемент из представления ... он отправляет всю дочернюю информацию с некоторым скрытым значением в контроллер проекта и автоматически снова добавляет / обновляет все дочерние элементы. чего мне не хватает?

Мои модели: Project & Workpackage

class Project < ActiveRecord::Base
  has_many :workpackages, :dependent => :destroy
  accepts_nested_attributes_for :workpackages
end
class Workpackage < ActiveRecord::Base
  belongs_to :project
end

Посмотреть _form

<%= nested_form_for @project do |f| %>
<% if @project.errors.any? %>
<div id="error_explanation">
    <h2><%= pluralize(@project.errors.count, "error") %> prohibited this project from being saved:</h2>
    <ul>
        <% @project.errors.full_messages.each do |msg| %>
        <li>
            <%= msg %>
        </li>
        <% end %>
    </ul>
</div>
<% end %>
<div class="field">
    <%= f.label :name %>
    <br />
    <%= f.text_field :name %>
</div>
<div class="field">
    <%= f.label :description %>
    <br />
    <%= f.text_field :description %>
</div>
<div>
    <%= f.fields_for :workpackages do |wp| %>
    <div class="field">
        <%= wp.label :title %>
        <br />
        <%= wp.text_field :title %>
    </div>
    <div class="field">
        <%= wp.label :wp_type %>
        <br />
        <%= wp.text_field :wp_type %>
    </div>
    <%= wp.link_to_remove 'Remove' %>
    <% end %>
    <%= f.link_to_add 'Add new WorkPackage', :workpackages %>
</div>
<div class="actions">
    <%= f.submit %>
</div>
<% end %>

и все мои классы контроллеров по умолчанию генерируются с помощью скаффолда. EDIT Сгенерированный Java-скрипт nested_form приведен ниже.

jQuery(function($) {
  window.NestedFormEvents = function() {
    this.addFields = $.proxy(this.addFields, this);
    this.removeFields = $.proxy(this.removeFields, this);
  };

  NestedFormEvents.prototype = {
    addFields: function(e) {
      // Setup
      var link    = e.currentTarget;
      var assoc   = $(link).attr('data-association');            // Name of child
      var content = $('#' + assoc + '_fields_blueprint').html(); // Fields template

      // Make the context correct by replacing new_<parents> with the generated ID
      // of each of the parent objects
      var context = ($(link).closest('.fields').find('input:first').attr('name') || '').replace(new RegExp('\[[a-z]+\]$'), '');

      // context will be something like this for a brand new form:
      // project[tasks_attributes][new_1255929127459][assignments_attributes][new_1255929128105]
      // or for an edit form:
      // project[tasks_attributes][0][assignments_attributes][1]
      if (context) {
        var parentNames = context.match(/[a-z_]+_attributes/g) || [];
        var parentIds   = context.match(/(new_)?[0-9]+/g) || [];

        for(var i = 0; i < parentNames.length; i++) {
          if(parentIds[i]) {
            content = content.replace(
              new RegExp('(_' + parentNames[i] + ')_.+?_', 'g'),
              '$1_' + parentIds[i] + '_');

            content = content.replace(
              new RegExp('(\\[' + parentNames[i] + '\\])\\[.+?\\]', 'g'),
              '$1[' + parentIds[i] + ']');
          }
        }
      }

      // Make a unique ID for the new child
      var regexp  = new RegExp('new_' + assoc, 'g');
      var new_id  = new Date().getTime();
      content     = content.replace(regexp, "new_" + new_id);

      var field = this.insertFields(content, assoc, link);
      $(link).closest("form")
        .trigger({ type: 'nested:fieldAdded', field: field })
        .trigger({ type: 'nested:fieldAdded:' + assoc, field: field });
      return false;
    },
    insertFields: function(content, assoc, link) {
      return $(content).insertBefore(link);
    },
    removeFields: function(e) {
      var link = e.currentTarget;
      var hiddenField = $(link).prev('input[type=hidden]');
      hiddenField.val(1);
      // if (hiddenField) {
      //   $(link).v
      //   hiddenField.value = '1';
      // }
      var field = $(link).closest('.fields');
      field.hide();
      $(link).closest("form").trigger({ type: 'nested:fieldRemoved', field: field });
      return false;
    }
  };

  window.nestedFormEvents = new NestedFormEvents();
  $('form a.add_nested_fields').live('click', nestedFormEvents.addFields);
  $('form a.remove_nested_fields').live('click', nestedFormEvents.removeFields);
});

1 Ответ

1 голос
/ 05 марта 2012

просто удалось найти решение.См. acceptpts_nested_attributes_for

Я должен был добавить :allow_destroy => true

class Project < ActiveRecord::Base
  has_many :workpackages, :dependent => :destroy
  accepts_nested_attributes_for :workpackages, :allow_destroy => true
end
...