ruby-on-rails - 表单提交时未添加嵌套字段

标签 ruby-on-rails ruby cocoon-gem

我正在使用 cocoon gem 来尝试添加一个属于另一个具有嵌套字段的对象。我有一个包含许多“里程碑”的“user_resolution”。我已经在这两个模型中相应地建立了关联。出于某种原因,里程碑无法创建,但是如果我在数据库中手动添加一个里程碑,我可以成功更新它。我可以动态添加字段并使用 cocoon gem 删除它们,仅此而已。当我单击“添加里程碑”时,它会将我重定向到用户解决方案的显示 View 并抛出成功消息,说明用户解决方案已更新,不会抛出任何错误,但不会创建里程碑。

user_resolution.rb

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

里程碑.rb

belongs_to :user_resolution

我已经在编辑 View 中设置了嵌套表单,因为现在我只希望用户在编辑 View 中为解决方案添加一个里程碑。

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>

用户分辨率 Controller 中允许的参数还包含以下内容

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

里程碑本身没有 View ,它们只有一个模型和一个 Controller 。 Controller 创建操作(我不确定嵌套表单是否需要)包含标准的以下代码

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

我已尽我所能提供信息,但如果您需要任何其他信息,请告诉我。谢谢大家。

最佳答案

which i'm unsure is required for nested forms

你不需要 create milestones 的行动- 它们将从 user_resolutions#create 填充 Controller Action 。

这有几件事要看。我会在这里详细介绍一些。这不是一个具体的答案,但可能会帮助您指明正确的方向。


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

Cocoon构建嵌套表单做得很好——您需要确保它符合 Rails 的嵌套属性结构。

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

f.fields_for部分(在 HTML 中不会这样称呼),您将查找与以下内容等效的内容:

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

需要注意的重要一点是名字...

每次您为此使用表单或任何 Rails View 助手时,您真的只是在构建标准的 HTML。 form_for只是创建一个 HTML 表单,因此其中包含的任何参数都需要遵循特定的结构,以便 Rails 识别这些参数。

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

以上命名结构需要查一下出处。如果你看到它,那很好。如果不是,则表示您没有正确构建表单。


其次,您需要确保在 Controller 中构建您的对象

我不确定如何 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 对嵌套属性做了什么,使您能够确定它们发生了什么。

抱歉冗长的回答。反正你不会收到任何答复,所以我觉得给你一些东西是明智的。

关于ruby-on-rails - 表单提交时未添加嵌套字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33454262/

相关文章:

c - 为什么我在调试 Ruby C 扩展时会在 gdb 中收到 SIGTRAP?

ruby-on-rails-4 - Rails 4.0 和 Cocoon : nested fields under fields_for don't appear in Edit

ruby - 为 REST API 创建动态 Ruby OpenAPI/Swagger 客户端的助手

ruby-on-rails - 如果父模型是新的并且在子模型中不是 NULL,则 ActiveAdmin has_many 表单不会保存

ruby-on-rails - Cocoon添加关联,如何限制关联数

ruby-on-rails - 带有设计的 Turbo-Rails 不会始终如一地重定向 Rails 6.1.3 设计 4.7.3 Turbo Rails 0.5.9

ruby-on-rails - 带有失败屏幕截图的 Rspec HTML 报告

ruby-on-rails - 使用 assert_select 查找选择框值?

javascript - 如何在 Rails 6 中禁用 TurboLinks?

ruby-on-rails - 在 rails 4 中重构一个大的 routes.rb 文件