DEV Community

hungle00
hungle00

Posted on

5 1

Rails nested form (new gem with Stimulus)

Nested forms are forms that handle nested models and attributes in one form; e.g. a project with its tasks or an invoice with its line items.

Before Rails 6, Cocoon is a good choice for creating dynamic nested forms. But Cocoon needs jQuery to work well, it's a very old library on modern-day frontend frameworks.
When Stimulus is came out, Rails devs is suggested to use Stimulus as Javascript library in their projects. So, I created a gem for handling dynamic nested forms with Stimulus JS.

GitHub logo hungle00 / rondo_form

Same as Cocoon, but using StimulusJS https://rubygems.org/gems/rondo_form

RondoForm

Handle dynamic nested forms, same as Cocoon, but using StimulusJS

Installation

Install the gem and add to the application's Gemfile by executing:

$ bundle add rondo_form

Or inside the Gemfile add the following

$ gem 'rondo_form', '~> 0.2.6'

Run the installation task:

$ rails g rondo_form:install

Usage

For example, you have Project model, which has has_many relationship with Task model:

rails g scaffold Project name:string description:string
rails g model Task description:string done:boolean project:belongs_to

You need to add accepts_nested_attributes_for to Project model:

class Project < ApplicationRecord
  has_many :tasks, dependent: :destroy
  accepts_nested_attributes_for :tasks, reject_if: :all_blank, allow_destroy: true
end

Sample with SimpleForm

The RondoForm gem adds two helper functions: link_to_add_association and link_to_remove_association. The example below illustrates the way to use it.

In your projects/_form partial:

<%= simple_form_for(@project) do |f| %>
  <div class="form-inputs">
    <%= f.input :name %>
    <%= f.input :description %>
  </div
Enter fullscreen mode Exit fullscreen mode

Rondo Form is easy to use, it has the same tag helpers name as cocoon: link_to_add_association, link_to_remove_association.
This gem does not need JS dependencies to work with, when you run under command, it will generate nested_rondo_controller.js in your app/javascript/controllers/ folder:



rails g rondo_form:install 


Enter fullscreen mode Exit fullscreen mode

And auto import this controller into index.js.


 js
import NestedRondoController from "./nested_rondo_controller"
application.register("nested-rondo", NestedRondoController)


Enter fullscreen mode Exit fullscreen mode

You must add data-controller="nested-rondo" to an element, that wraps fields_for and link_to_add_association helper.
For example, we have Project model, which has has_many relationship with Task model.
In your projects/_form partial:


 erb
<%= simple_form_for(@project) do |f| %>
  <div class="form-inputs">
    <%= f.input :name %>
    <%= f.input :description %>
  </div>
  <h3>Tasks</h3>
  <div data-controller="nested-rondo">
    <%= f.simple_fields_for :tasks do |task| %>
      <%= render "task_fields", f: task %>
    <% end %>
    <div class="links">
      <%= link_to_add_association "Add Task", f, :tasks %>
    </div>
  </div>
  <%= f.button :submit %>
<% end %>


Enter fullscreen mode Exit fullscreen mode

In your _task_fields partial:


 erb
<div class="nested-fields">
  <%= f.input :description %>
  <%= f.input :done, as: :boolean %>
  <%= link_to_remove_association "Remove Task", f %>
</div>


Enter fullscreen mode Exit fullscreen mode

This sample I built with SimpleForm gem, but the idea is the same with Rails standard form.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (1)

Collapse
 
marcelonmoraes profile image
Marcelo Moraes

Excelent.

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs