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

Copy Text
rails new cocoon-gem-example

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

Copy Text
yarn add jquery

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

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

Copy Text
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

Copy Text
# 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.

Copy Text
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.

Copy Text
require('jquery')
import "cocoon";

7. Run this command to install cocoon gem

Copy Text
bundle install

8. Generate User model

Now, generate a User model

Copy Text
rails g model User

9. Generate Friend model

Generate Friend model with the help of the following command:

Copy Text
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

Copy Text
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

Copy Text
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.

Copy Text
$ rails db:migrate

12. Update the model file

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

Copy Text
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

Copy Text
class Friend < ApplicationRecord
 belongs_to :user
end

14. Generate User controller

Copy Text
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).

Copy Text
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.

Copy Text
<%= 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.

Copy Text
<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

Copy Text
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

Copy Text
<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.

Hire Ruby on Rails Developer

Connect Now

Build Your Agile Team

Hire Skilled Developer From Us

[email protected]

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.

How Can We Help You?