使用 Cocoon 在 link_to_add_association 点击时自动添加嵌套的子部分
Posted
技术标签:
【中文标题】使用 Cocoon 在 link_to_add_association 点击时自动添加嵌套的子部分【英文标题】:Automatically adding nested child partials on link_to_add_association click using Cocoon 【发布时间】:2020-12-08 03:41:53 【问题描述】:我有一个包含 4 个嵌套级别的表单,我用它来动态添加商品、发货和计算成本。我已将表单设置为可以通过单击按钮添加/删除所需的所有内容。页面初始渲染的一切都符合预期。
但是,当我添加中级嵌套的新实例(SubQuote 和 QuoteShipment)时,它只会呈现自身(例如 SubQuote),而不是在其部分(QuoteShipment)中引用的任何部分。我想要一个按钮来自动渲染它下面的所有嵌套部分。
我的相关模型是结构化的:
class Quote < ApplicationRecord
has_many :sub_quotes, dependent: :destroy, inverse_of: :quote
accepts_nested_attributes_for :sub_quotes, reject_if: :all_blank
end
class SubQuote < ApplicationRecord
belongs_to :quote
has_many :quote_shipments, dependent: :destroy, inverse_of: :sub_quote
accepts_nested_attributes_for :quote_shipments, reject_if: :all_blank
end
class QuoteShipment < ApplicationRecord
has_many :quote_items, dependent: :destroy, inverse_of: :quote_shipment, class_name: "::QuoteItem"
belongs_to :sub_quote
accepts_nested_attributes_for :quote_items, reject_if: :all_blank
end
Class QuoteItem < ApplicationRecord
belongs_to :quote_shipment
end
在页面加载时呈现 QuoteShipment 部分的 SubQuote 类的部分,而不是在 link_to_add_association 点击时。
<div class="col nested-sub_quote-fields" id="sub_quote_identifier">
<div class="row">
<%= link_to_remove_association button_tag('remove sub_quote', type: "button", class: "btn btn-sm btn-outline red-btn add-quote"), f , wrapper_class: "nested-sub_quote-fields" %>
</div>
<div class="row" class="">
<div id="sub_quote" class="col mt-0 mt-md-4 mb-4 p-0">
<div class="col ">
<div class="col-lg col-sm-12 col-md-12">
<%= f.fields_for :quote_shipments do |shipment| %>
<%= render partial: "quotes/quote_shipment_fields", :locals => :f => shipment %>
<% end %>
<div class='links'>
<%= link_to_add_association button_tag('Add Shipment', type: "button", class: "btn btn-sm btn-outline btn-primary add-quote"), f, :quote_shipments %>
</div>
</div>
</div>
</div>
<div class="col-lg-5 col-sm-12 col-md-12">
<%= render partial: "quotes/cost", locals: f: f %>
</div>
</div>
</div>
以上述关系为例:
如果我单击 SubQuote 类的 link_to_add_association,我希望它呈现 SubQuote 部分,以及 QuoteShipment 部分的 1 个实例和 QuoteItem 部分的 1 个实例。
如果我单击了 QuoteShipment 部分的 link_to_add_association,我希望它使用嵌套在新 QuoteShipment 部分下方的 QuoteItem 部分的 1 个实例来呈现。
我试过了:
在 Jquery 中使用“insert-after”方法,但部分需要 fields_for 变量,我认为该变量无法访问 在控制器上实例化更多实例 大量谷歌搜索。要么没有人问这个问题,要么我搜索的方式错误我认为在更糟糕的情况下,我可以为我拥有的每个不同级别的 link_to_add_association 按钮生成不同的部分,但这似乎非常多余
【问题讨论】:
【参考方案1】:link_to_add_association
具有:wrap_object
选项(检查documentation),允许在渲染部分之前添加额外的初始化。
所以在你的情况下,你可以这样:
= link_to_add_association button_tag('Add Shipment', type: "button", class: "btn btn-sm btn-outline btn-primary add-quote"),
f, :quote_shipments,
wrap_object: Proc.new|shipment| shipment.quote_items.build; shipment
在wrap_object
部分内,您可以进行任何您想要的初始化,只要您返回要呈现的嵌套项(在本例中为shipment
)。
在这个例子中,我们将 build
和 QuoteItem
进行渲染。
对于SubQuote
,你可以做类似的事情。例如。像
wrap_object: Proc.new|sub_quote| shipment = sub_quote.quote_shipments.build; shipment.quote_items.build; sub_quote
【讨论】:
这正是我所需要的!非常感谢!另外,感谢您构建如此令人头疼的节省 Gem以上是关于使用 Cocoon 在 link_to_add_association 点击时自动添加嵌套的子部分的主要内容,如果未能解决你的问题,请参考以下文章
使用 simple_form 和 cocoon 时无法让 select2 工作
使用 Cocoon 在 link_to_add_association 点击时自动添加嵌套的子部分
Rails cocoon嵌套字段,在编辑表单上呈现每个字段旁边的现有图像