Quick Summary:

There are innumerable gems available for the ROR framework. Cocoon is one of those gems. If you haven’t explored much about the Cocoon Gem, then don’t worry! In this step-by-step guide, we will implement Cocoon gem example and learn more about it. So, get ready to code and integrate cocoon gem!

Table of Contents

Introduction

In this tutorial, we learn how to create complex and dynamic rails form using the cocoon gem in Ruby on Rails.

Suppose you want to create a form in which you want your users to enter their friends’ names. You do not know in advance how many friends your user will have, so how to add a specific number of fields in the layout?

Rails do not have any built-in support to answer this question. Thus, to resolve this issue, we can use cocoon gem. Cocoon powers nested forms with JavaScript, allowing fields to be added or removed dynamically.

In this cocoon gem example, we will see how to use cocoon gem to add or remove nested fields asynchronously without generating a new request. We will develop a demo where users can add n number of friends. So, the friend’s name will be a nested attribute of the user’s name.

cocoon gem

Goal of Cocoon Gem Tutorial

Before starting with our Cocoon gem example, let’s see the video of the nested form which we will implement.

Cocoon Gem Example: Steps to Implement Cocoon Gem in Rails 6.

Let’s understand how to use cocoon gem in Rails 6 step by step guide to implement Cocoon Gem in your Ruby on Rails project.

1. Create a new rails app

rails new cocoon-gem-example

2. Now, add jquery to the project using the following command:

yarn add jquery

3. Update the config/webpack/environment.js file

Update the config/webpack/environment.js file with the following code

const { environment } = require('@rails/webpacker')
 
const webpack = require('webpack')
environment.plugins.prepend('Provide',
   new webpack.ProvidePlugin({
       $: 'jquery/src/jquery',
       jQuery: 'jquery/src/jquery'
   })
)
 
module.exports = environment

4. Add the cocoon gem to the Gemfile

# Unobtrusive nested forms handling, using jQuery. Use this & discover cocoon-heaven.
gem 'cocoon'

5. Add and install the cocoon gem using bundle

Adding and installing the cocoon gem using the bundle will not completely install the cocoon gem for the app. For that, we also need to add the companion package for cocoon using yarn.

yarn add github:nathanvda/cocoon#c24ba53

6. Add app/javascript/packs/application.js file.

Add the following two lines in the app/javascript/packs/application.js file.

require('jquery')
import "cocoon";

7. Run this command to install cocoon gem

bundle install

8. Generate User model

Now, generate a User model

rails g model User

9. Generate Friend model

Generate Friend model with the help of the following command:

rails g model Friend

10. Edit the migration files

Now, edit the migration files generated while executing the above two commands. The file name will be like 20210427114709_create_users.rb and 20210427114810_create_friends.rb present inside the db/migrate directory.

db/migrate/20210427114709_create_users.rb

class CreateUsers < ActiveRecord::Migration[6.1]
 def change
   create_table :users do |t|
     t.string :name, null: false
     t.timestamps
   end
 end
end

db/migrate/20210427114810_create_friends.rb

class CreateFriends < ActiveRecord::Migration[6.1]
 def change
   create_table :friends do |t|
     t.references :user, null: false, foreign_key: true
     t.string :friend_name, null: false
     t.timestamps
   end
 end
end

11. Save the above file

Now, save the above file after making changes; it’s time to migrate to reflect the above changes in the application’s schema.

$ rails db:migrate

12. Update the model file

Now, update the model file of User, i.e., app/models/user.rb

class User < ApplicationRecord
 has_many :friends, dependent: :destroy
 accepts_nested_attributes_for :friends
end

13. Same like above, we need to make changes in the model file of Friend, i.e., app/models/friend.rb

class Friend < ApplicationRecord
 belongs_to :user
end

14. Generate User controller

rails g controller users

15. Open app/controllers/users_controller.rb

Open app/controllers/users_controller.rb and write the below-mentioned code. Here, as you can see, we have added the _destroy virtual attribute inside the permitted parameters for the user. The reason is to destroy the nested fields (with the delete button).

class UsersController < ApplicationController
 def new
   @user = User.new
   @friends = @user.friends.build
 end
 
 def create
   @user = User.new(user_params)
   if @user.save
     redirect_to user_path(@user)
   else
     render action: :new
   end
 end
 
 def show
   @user = User.find(params[:id])
   @friends = @user.friends
 end
 
 private
 
 def user_params
   params.require(:user).permit(:name, friends_attributes: [:id, :friend_name, :_destroy])
 end
end

16. Create a new file

Moving towards the UI part now. Create a new file – new.html.erb inside app/views/users directory and add the following code. We have used a helper function link_to_add_association provided by the cocoon gem. This function will add a link so that we can use it to add a new field dynamically.

<%= form_for(@user) do |f| %>
  <br>
  <br>
  <div>
    <div>
      <%= f.label :name %>
      <%= f.text_field :name %>
    </div>

    <div>
      <%= f.fields_for :friends do |t| %>
        <%= render "friend_fields", :f => t %>
      <% end %>
      
      <div>
        <br>
        <%= link_to_add_association "Add Friend", f, :friends %> <!-- (*) -->
      </div>
    </div>
    
    <div>
      <br>
      <%= f.submit %>
    </div>
  </div>
<% end %>

17. Create another file in the same directory

Similarly, create another file in the same directory as of new.html.erb with the name _friend_fields.html.erb and add the following code. We have implemented another helper function link_to_remove_association provided by the cocoon gem to delete a field dynamically from the layout.

<div class="nested-fields">
   <%= f.label "Friend's name" %>
   <%= f.text_field :friend_name %>
  
   <%= link_to_remove_association "Delete", f %>
</div>

18. Update the config/routes.rb file

Now, it’s time to update the config/routes.rb file with the following code

Rails.application.routes.draw do
 root 'users#new'
 
 resources :users
 
 # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

19. Create a show.html.erb file

Create a show.html.erb file in the app/views/users directory and update it with the below-mentioned code

<h4><%= @user.name %>'s Friends</h4>
 
<% @friends.each do |friend| %>
 <li><%= friend.friend_name %></li>
<% end %>

Here’s the entire source code for the cocoon gem example – Github Repository

You May Also Like to Read: How to Download and Install Ruby Gems into Gemfile

Conclusion

So, this was about how to implement cocoon gem example. I hope the tutorial has helped you the way you wanted. If you’re a ROR enthusiast and want to learn more about Ruby on Rails then visit ROR tutorials and start exploring!

Bacancy Technology has dedicated, experienced, and industry’s best ROR developers who have mastered Rails’ basic and advanced concepts. Are you looking for assistance to help you with your Ruby on Rails project requirements? Then without any further delay, contact Bacancy Technology and hire ruby on rails developer from us. You’ll never regret your decision to work with Bacancy.

Kishan Aghera

Kishan Aghera

Sr. Software Engineer at Bacancy

Ruby on Rails engineer crafting efficient, robust, and innovative software solutions.

MORE POSTS BY THE AUTHOR
SUBSCRIBE NEWSLETTER

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.