【问题标题】:Can you the coccon gem without a direct nested association?您可以在没有直接嵌套关联的情况下使用 coccon gem 吗?
【发布时间】:2019-04-01 11:53:43
【问题描述】:

我必须将我的表单转换为不使用嵌套关联。换句话说,而不是

<%= link_to_add_association f, :contacts, class: 'btn btn-primary', partial: 'projects/contact_fields', data: {
    association_insertion_node: '.contact_fields', association_insertion_method: :append
} do %>
    <i class="fas fa-plus"></i>
<% end %>

<%= f.fields_for :contacts do |contact| %>
    <%= render 'projects/contact_fields', f: contact %>
<% end %>

我希望能够只传递一个用作容器的字符串(类似于使用 field_for 的方式)。

<%= link_to_add_association 'contacts[]', 'projects/contact_fields', class: 'btn btn-primary', partial: 'projects/contact_fields', data: {
    association_insertion_node: '.contact_fields', association_insertion_method: :append
} do %>
    <i class="fas fa-plus"></i>
<% end %>

<% @contacts.each_with_index do |contact, index| %>
    <%= fields_for "contacts[#{index}]", contact do |c| %>
        <%= render 'projects/contact_fields', f: c %>
    <% end %>
<% end %>

【问题讨论】:

  • Cocoon 使用关联来确定如何创建要插入的对象,因此使用字符串"contacts[]" 将不起作用。你实际上想要完成什么?您没有实际的嵌套关系,但想要编辑/管理数组或集合?
  • 是的......这正是我想做的......只是不知道如何正确地问这个问题。

标签: cocoon-gem


【解决方案1】:

Cocoon 目前无法编辑/管理收藏。 Cocoon 只是帮助 Rails 中嵌套子项功能的表单行为,因此没有简单的解决方案来编辑​​数组或集合。另一方面,这通常很容易在没有茧的情况下实现。

非常高的水平,做这样的事情:

@contacts.each do |contact| 
  = render `contacts/edit`, contact: contact 
= render `contacts/new`

因此为每个现有联系人呈现编辑表单,并呈现一个空的新表单。您将不得不稍微编辑您的控制器功能,因为您将始终重新呈现完整的集合/索引页面(包含集合中的所有现有联系人?)。

因此您可以在一个页面上呈现多个表单。使用 turbolinks 这将快速渲染并且感觉实际上完全一样。您可以使用 xhr 仅更新页面的特定部分,但开始时甚至不需要。

【讨论】:

    【解决方案2】:

    所以我最终关注drifting ruby 并使用cocoon gem 中的代码自己实现了一些东西。我希望其他人可以从中受益。感谢 nathanvda 提供的 cocoon gem,它帮助我编写了下面的代码,真希望我能使用它:

    将此添加到您的 app/helpers/application_helper.rb

    def link_to_add_row(*args, &block)
        if block_given?
            link_to_add_row(capture(&block), *args)
        else
            #byebug
            name, association, new_object, partial, html_options = *args
            html_options ||= {}
            html_options[:class] = [html_options[:class], "custom_add_fields"].compact.join(' ')
            id = 'NEW_RECORD'
            fields = fields_for("#{association}[#{id}]", new_object, child_index: id) do |builder|
                #byebug
                render( partial, f: builder)
            end
            fields = CGI.escapeHTML(fields).html_safe
            link_to(name, '#', class: html_options[:class], data: {id: id, fields: fields})
        end
    end
    

    添加到您的 app/assets/application.js

    $(document).on('click', '.custom_remove_fields', function(event) {
        $(this).prev('input[type=hidden]').val('1');
        $(this).closest('tr').hide();
        return event.preventDefault();
    });
    
    $(document).on('click', '.custom_add_fields', function(event) {
        var regexp, time;
        time = new Date().getTime();
        regexp = new RegExp($(this).data('id'), 'g');
        $('.contact_fields').append($(this).data('fields').replace(regexp, time));
        return event.preventDefault();
    });
    

    在您的模板中,您可以使用以下内容为集合呈现部分内容:

    <%= link_to_add_row('contacts', contact.new, 'contact_fields', class: 'btn btn-primary') do %>
        <i class="fas fa-plus"></i>
    <% end %>
    

    这就是我使用模板中的集合呈现部分的方式:

    <tbody class="contact_fields">
      <% @contacts.each_with_index do |contact, index| %>
          <%= fields_for "contacts[#{index}]", contact do |c| %>
              <%= render 'contact_fields', f: c %>
          <% end %>
      <% end %>
    </tbody>
    

    这就是我的 contact_fields.html.erb 部分的样子。

    <tr class="nested-fields">
      <td>
        <%= f.text_field :fullname, class: 'form-control invoke-contacts-search contact-fullname' %>
      </td>
      <td>
        <%= f.text_field :email, class: 'form-control invoke-contacts-search contact-email' %>
      </td>
      <td>
        <%= f.text_field :phone, class: 'form-control contact-phone' %>
      </td>
      <td>
        <%= f.text_field :department, class: 'form-control contact-department' %>
      </td>
      <td>
        <%= f.text_field :manager, class: 'form-control contact-manager' %>
      </td>
      <td>
        <%= f.hidden_field :id %>
        <%= f.hidden_field :_destroy %>
        <%= link_to '#', class: 'btn btn-danger custom_remove_fields' do %>
            <i class="fas fa-trash-alt"></i>
        <% end %>
      </td>
    </tr>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-27
      • 2020-10-15
      • 2021-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-21
      • 2013-05-28
      相关资源
      最近更新 更多