未在表单提交上添加嵌套字段

时间:2015-10-31 17:06:50

标签: ruby-on-rails ruby cocoon-gem

我正在使用cocoon gem来尝试添加一个属于另一个具有嵌套字段的对象。我有一个' user_resolution'它有许多里程碑'。我已经在这两个模型中相应地建立了关联。由于某种原因,里程碑无法创建,但是如果我在数据库中手动添加一个里程碑,我可以成功更新它。我可以动态添加字段并使用cocoon gem删除它们,但这就是全部。当我点击添加里程碑'它将我重定向到用户解析的show视图,并抛出成功消息,表示用户解析已更新,不会抛出任何错误,但未创建里程碑。

user_resolution.rb

has_many :milestones
accepts_nested_attributes_for :milestones, reject_if: :all_blank, allow_destroy: true

milestone.rb

belongs_to :user_resolution

我已在编辑视图中设置了嵌套表单,因为现在我只希望用户在编辑视图中将里程碑添加到分辨率。

user_resolutions / edit.html.erb

<%= form_for(@user_resolution) do |f| %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>

    <%= f.fields_for :milestones do |milestone| %>
      <%= render 'milestone_fields', f: milestone %>
    <% end %>

    <%= link_to_add_association 'Add Milestone', f, :milestones %>
    <%= f.submit "Add Milestone" %>

<% end %>

_milestone_fields.html.erb

<div class="nested-fields">
   <div class="field-row">
       <%= f.label :name, 'Name' %>
       <%= f.text_field :name %>
   </div>
   <div class="field-row">
       <%= f.label :description, 'Name' %>
       <%= f.text_area :description %>
   </div>
   <div class="field-row">
       <%= f.label :severity, 'severity' %>
       <%= f.check_box :severity %>
   </div>
   <div class="field-row">
       <%= f.label :target_date, 'target_date' %>
       <%= f.date_select :target_date %>
   </div>

   <%= link_to_remove_association 'Remove', f %>

</div>

用户分辨率控制器中的允许参数也包含以下

milestones_attributes: [:id, :user_resolution_id, :name, :description, :target_date, :severity, :complete, :_destroy]

里程碑本身没有视图,只有模型和控制器。控制器创建操作(我不确定嵌套表单是否需要)包含标准的以下代码

def create
    @milestone = Milestone.new(milestone_params)

    if @milestone.save
        redirect_to user_resolutions_path, 
        :flash => { :success => "You successfully created a milestone" }
    else
        redirect_to new_milestone_path, 
        :flash => { :error => "Oops something went wrong. Try again." }
    end
end

我尽可能提供信息,但如果您需要任何其他信息,请告诉我。谢谢你们。

1 个答案:

答案 0 :(得分:1)

  

我不确定嵌套表格是否需要

您不需要对create进行milestones操作 - 他们将从user_resolutions#create控制器操作中填充。

有几点需要注意。我在这里详细介绍一下。这不是一个具体的答案,但可能会帮助您指明正确的方向。

首先,您需要确保您收到正确的参数

Cocoon在构建嵌套表单方面做得非常出色 - 您需要确保它能够使用Rails&#39;嵌套属性结构。

为此,您应该right-click > view source

f.fields_for部分(在HTML中不会被称为)中,您将寻找与以下内容相同的内容:

<input type="text" name="milestones_attributes[0][name]" value="">

需要注意的重要事项是名称 ...

每次使用表单或任何 Rails视图帮助程序时,您都 只是构建标准HTML。 form_for只是创建一个HTML表单,因此其中包含的任何参数都需要遵循某个结构才能让Rails识别这些参数。

f.fields_for元素通常被称为x_attributes[:id][:param] - 这被传递给Rails,它遍历每个[:id]以确定要添加的嵌套参数的数量。

您需要检查上述命名结构的来源。如果你看到它,那很好。如果没有,这意味着您没有正确构建表单。

其次,您需要确保您的对象在控制器中构建

我不确定Cocoon如何做到这一点,但实质上,每次使用f.fields_for时,都必须先构建相关对象:

def new
    @user_reservation = UserReservation.new
    @user_reservation.milestones.build #-> this is what makes f.fields_for work
end

如果第一步显示不正确的元素命名,则表示您的关联对象未构建(这就是他们未被识别的原因)。

要测试它,您应该在发送之前在 new 方法中构建关联对象。

最后,您要发布您的参数

这些内容详细告诉您Rails正在对嵌套属性做什么,让您可以确定它们发生了什么。

很抱歉这个冗长的回答。你还是没有收到任何答案,所以我觉得给你一些东西是明智的。