你可以没有直接嵌套关联的茧宝石吗?

问题描述 投票:0回答:2

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

<%= 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-gem
2个回答
0
投票

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

非常高的水平,做类似的事情:

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

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

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


0
投票

所以我最终关注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>
© www.soinside.com 2019 - 2024. All rights reserved.