我正在使用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
我尽可能提供信息,但如果您需要任何其他信息,请告诉我。谢谢你们。
答案 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正在对嵌套属性做什么,让您可以确定它们发生了什么。
很抱歉这个冗长的回答。你还是没有收到任何答案,所以我觉得给你一些东西是明智的。