【问题标题】:Add clone button on each nested child object with Cocoon and Rails使用 Cocoon 和 Rails 在每个嵌套子对象上添加克隆按钮
【发布时间】:2021-05-17 11:15:06
【问题描述】:

我有一个父母,我可以添加多个孩子,我想在每个孩子中添加一个带有茧的克隆按钮。

按照next solution我做了这个代码:

这些是模型:

class MantenimientoSetup < ApplicationRecord
  has_many :actuation_setups, inverse_of: :mantenimiento_setup, validate: true, autosave: true, dependent: :destroy
  accepts_nested_attributes_for :actuation_setups, allow_destroy: true, reject_if: :all_blank
end
class ActuationSetup < ApplicationRecord
  belongs_to :mantenimiento_setup, inverse_of: :actuation_setups
end

我必须从子部分中添加克隆按钮... parent and child form

但是对于每个嵌套的新子对象,我都需要这个按钮,如下所示: enter image description here

这些是父子部分:

<!-- views/mantenimiento_setups/_form.html.erb -->
<%= form_for @mantenimiento_setup do |f| %>
  ...
  ...
  ...

  <div class="panel panel-default">
    <div class="panel-heading">
      <h4 class="panel-title">Configuraciones</h4>
    </div>
    <div class="panel-body mantenimiento-setup-element">
      <%= f.fields_for :actuation_setups do |act_setup_builder| -%>
        <%= render 'actuation_setup_fields', f: act_setup_builder %>
        <%= link_to_add_association 'Clone', f, :actuation_setups, data: {"association-insertion-node" => ".mantenimiento-setup-element", "association-insertion-method" => "append"}, wrap_object: Proc.new {|d| d = act_setup_builder.object.dup; d}, class: "btn btn-info btn-sm" %>
      <% end -%>
    </div>
    <div class="panel-footer">
      <%= link_to_add_fields 'Add new setup', f, :actuation_setups, {mantenimiento_setup: f.object}, {class: "btn btn-success", nested_form: "/mantenimiento_setups/actuation_setup_fields" }%>
    </div>
  </div>

  <%= save_button %>
<% end %>
<!-- views/mantenimiento_setups/_actuation_setup_fields.html.erb -->
<div class='row fields'>
  <div class="col-md-3 actuation-type-div-selector">
    
  ...
  ...
  ...

  <div class="col-md-1">
    <label class="control-label invisible">...</label><br/>
    <%= link_to_remove_fields "Remove", f%>
  </div>

</div>

如果我将克隆按钮粘贴到子部分中,请关闭以删除按钮...

<!-- views/mantenimiento_setups/_actuation_setup_fields.html.erb -->
<div class='row fields'>
  <div class="col-md-3 actuation-type-div-selector">
    
  ...
  ...
  ...

  <div class="col-md-1">
    <label class="control-label invisible">...</label><br/>
    <%= link_to_remove_fields "Remove", f%>
  </div>

  <div class="col-md-1">
    <label class="control-label invisible">...</label><br/>
    <%= link_to_add_association 'Clone', f, :actuation_setups, data: {"association-insertion-node" => ".mantenimiento-setup-element", "association-insertion-method" => "append"}, wrap_object: Proc.new {|d| d = act_setup_builder.object.dup; d}, class: "btn btn-info btn-sm" %>
  </div>
</div>

它返回此错误是因为我正在从子到子关联调用关联不存在:

Association actuation_setups doesn't exist on ActuationSetup

如何为每个孩子添加一个克隆按钮?

【问题讨论】:

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


    【解决方案1】:

    link_to_add_association 需要来自父级(定义关联)的表单对象 (f)。因此,在嵌套级别,您需要了解父表单对象。

    另外:如果记录已经存在,我们只想渲染Clone 按钮。也许我应该更好地解释一下:表单和所有Clone-partials 都在服务器上呈现,因此如果它们在表单中被编辑/更改,则不会复制字段。明白了吗?为了能够做到这一点,我们需要更多的 javascript 代码,这也可能是一种非常有效的方法,也许更简单:触发link_to_add_association 链接,在cocoon:after-insert 事件中,我们可以预填充从 to 复制的字段-被克隆的项目,如果有的话。但是,如前所述,那将是一个纯 JavaScript 解决方案。

    为了与您最初的建议保持一致,您的视图看起来像(我没有复制整个视图)

    <!-- views/mantenimiento_setups/_form.html.erb --> 
    
    <%= f.fields_for :actuation_setups do |act_setup_builder| -%>
      <%= render 'actuation_setup_fields', f: act_setup_builder, parent_f: f %>
    <% end -%>
    

    然后您可以在嵌套形式中编写:

    <!-- views/mantenimiento_setups/_actuation_setup_fields.html.erb -->
    <div class='row fields'>
      <div class="col-md-3 actuation-type-div-selector">
            
      <div class="col-md-1">
        <label class="control-label invisible">...</label><br/>
        <%= link_to_remove_fields "Remove", f%>
      </div>
    
      <% if local_assigns.has_key?(:parent_f) %>
        <div class="col-md-1">
        
          <%= link_to_add_association 'Clone', parent_f, :actuation_setups, data: {"association-insertion-node" => ".mantenimiento-setup-element", "association-insertion-method" => "append"}, wrap_object: Proc.new {|d| d = act_setup_builder.object.dup; d}, class: "btn btn-info btn-sm" %>
        </div>
      <% end %>
    </div>
    

    (我的 erb 有点生疏了,我总是写 haml 或 slim,因为我发现它们更易读,打字工作更少,所以可能有一些拼写错误)。

    简而言之:对于每个现有的:actuation_setup,我们传递parent_f 参数(父表单对象),并在嵌套的子对象中检查该参数是否被给出,如果是,我们知道它是一个现有的孩子,然后我们添加克隆链接,并使用父表单对象能够添加一个新的嵌套孩子作为现有/给定嵌套孩子的副本。

    【讨论】:

    • 感谢您的解释!你很棒!!另一个关于 javascript 代码的问题,您是否有一个示例可以知道如何预填充从要克隆的项目中复制的字段?对于表单中的新/编辑的孩子,我将需要这个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 2020-12-08
    相关资源
    最近更新 更多