问题描述
我有一个具有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,inverse_of: :sub_quote
accepts_nested_attributes_for :quote_shipments,reject_if: :all_blank
end
class QuoteShipment < ApplicationRecord
has_many :quote_items,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
用于SubQuote类的局部,在页面加载时呈现QuoteShipment部分,但在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',class: "btn btn-sm btn-outline btn-primary add-quote"),: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部分,1个QuoteShipment部分实例和1个QuoteItem部分实例。
-
如果单击QuoteShipment部分的link_to_add_association,我希望它使用嵌套在新QuoteShipment部分下面的QuoteItem部分的1个实例进行渲染。
我尝试过:
- 在Jquery中使用“ insert-after”方法,但是部分对象需要我认为无法访问的fields_for变量
- 在Controller上实例化更多实例
- 大量使用Google搜索。要么没人问这个问题,要么我搜索错误的方式
我认为在更坏的情况下,我可以为每个不同级别的link_to_add_association按钮生成不同的部分,但这似乎很多余
解决方法
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 }