Rails Fields_for And Accepts_nested_attributes_for: How To Add Or Remove Without Cocoon Gem

Posted By Weston Ganger

In a vanilla Rails project that doesnt have the cocoon gem could use this approach to handle adding and removing nested attributes entries using fields_for and accepts_nested_attributes_for.

It can be quite difficult to remember how exactly to do this so I showcase it here.

<%= form_for @post do |f| %>
  <div class="comments-wrapper">
    <% f.fields_for :comments do |f2| %>
      <%= render "comment_fields", f: f2 %>
    <% end %>
  </div>

  <button type="button" class="add-comment">Add Comment</button>

  <script>
    $(function(){
      $(".add-comment").click(function(){
        var uniqueId = crypto.randomUUID();
        // OR
        var uniqueId = Date.now().toString(36) + Math.random().toString(36).substring(2);
        // OR
        var uniqueId = $(".comment-container").length;

        var html = "#{j f.fields_for(:comments, @post.comments.new, child_index: 'REPLACE_ID'){|f2| render('comment_fields', f: f2) }}";

        html.replace(/REPLACE_ID/g, uniqueId);

        $(".comments-wrapper").append(html);
      });

      $(document).on("click", ".delete-comment", function(){
        var container = $(this).closest(".comment-container");
        container.find("input[name$='[_destroy]']").val("1");
        container.hide();
      });
    });
  </script>
<% end %>



### _comment_fields.html.erb

<div class="comment-container">
  <!-- Other comment fields here -->

  <%= f.hidden_field :_destroy %>
  <button type="button" class="delete-comment">Delete Comment</button>
</div>

Related External Links:

Article Topic:Software Development - Ruby / Rails

Date:June 02, 2023