Rails嵌套表单 - 动态添加所有获取零索引的项目

时间:2012-03-15 22:32:56

标签: ruby-on-rails nested-forms nested-attributes

我的嵌套表单有问题。我正在使用Ryan Bates的代码。 Gemfile片段:

gem“nested_form”,:git => 'https://github.com/ryanb/nested_form.git'

问题在于,当我尝试使用* link_to_add *时,我得到一个看起来很正常的新项目,但它不起作用,因为它根据当前时间获得0的新索引而不是“随机”索引应该生成nested_form.js。我添加的每个项目都获得相同的0索引。因此效果是我无法添加新项目(或者只保存最后一个新项目,具体取决于模型的原始状态)。

新父对象和编辑父对象时的行为相同。

我很确定我做错了,因为我能够做一个简单的新应用程序。但我无法弄清楚我的真实应用程序出了什么问题。

为我的(工作)测试应用和我的(不工作)真实应用生成的nested_form.js是相同的。所以我不认为版本差异存在问题。

我使用Firebug来遍历nested_form.js中的代码,但无法弄清楚它为什么会在那里生成0索引。

我的父模型有:

课程<的ActiveRecord ::基

accepts_nested_attributes_for :levels, :allow_destroy => true
has_many :levels, :dependent => :destroy, :order => :depth

我的表单实例化如下:

<%= nested_form_for(@course) do |f| %>

嵌套对象的部分是这样的:

<%= f.fields_for :levels do |builder| %>
    <tr>
        <td><%= builder.text_field :name %></td>
        <td><%= image_tag(builder.object.icon) unless (builder.object.icon.nil?) %></td>
        <td><%= builder.link_to_remove "Remove" %></td>
    </tr>
<% end %>
   <tr><td><%= f.link_to_add "Add a level", :levels %></td></tr>

我认为我的代码和我的工作示例(或我见过的其他示例)之间没有任何区别。

有没有人有任何想法?

更新:

在Firebug中尝试调试之后,我意识到nested_form.js中的addFields函数使用的'blueprint'在addFields方法中被更改了,这就是为什么它没有放入生成的索引(该块是被我的测试应用程序绕过)。所以我通过更改:

来覆盖发生这种情况的块
if (context) {

为:

if (false)

这似乎可以解决我的初步测试症状,但我觉得在某些情况下(NPI)这可能会破坏别的东西(可能有多层嵌套?)。

3 个答案:

答案 0 :(得分:2)

虽然我觉得有点傻,但我觉得这可能会发生在其他人身上(我在问题中说过我可能做错了')。

我正在做的'错'是我使用字段集来隔离我的表单区域。而且我给了田野相关的课程“领域”。不好。与表单生成器的类冲突。

答案 1 :(得分:1)

当我的父对象没有自己的任何字段时,我遇到了类似的情况:

Carousel has_many Items
<%= f.inputs 'Carousel' do %>
<!-- NOTICE NO FIELDS HERE -->

  <f.fields_for :items, allow_destroy: true do |it| %>
    <%= it.input :media_hash %>
    <%= it.link_to_remove 'Remove item' %>
  <% end %>
  <%= f.link_to_add 'Add item', :items %>
<% end %>

通过在父对象上添加字段,正在正确创建索引。就我而言,我只是将f.input :created_at, as: :hidden添加到我的Carousel。

答案 2 :(得分:0)

我有完全相同的问题(在更新时,而不是创建),除了我的html中的“字段”类的唯一实例是由fields_for帮助程序生成的,所以非常沮丧。

花了将近一整天的时间来逐步完成javascript,但是没有理由说它应该用无效的“0”索引替换“new_”字符串。

修复它的黑客是在内容编辑循环中添加一个检查:

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