1
1

More than 1 year has passed since last update.

脱jQueryによるcocoonの使い方

Last updated at Posted at 2022-07-19

概要

1対多のテーブル構造において、小テーブルのフォームを複数作成するためのGem。
また、公式には、「このgemはjQueryに依存しているので、すでにjQueryを使用しているRailsプロジェクトで最も有効」とあるが、脱jQueryを実施しているプロジェクトではVanilla JS版もある。
今回は脱jQueryで実装する。
導入が違うだけで実装方法はごく普通のcocoon。

テーブル設計

投稿(post)が1に対してジャンル(genre)が多

導入手順

まずはGemfileに追加。

gem 'cocoon'


CDNにて導入。
私はimportmap採用でnode.js/yarnを極力排除したので、CDNにて導入。
(他に何かいい方法があれば教えてください)

<script src='https://unpkg.com/@oddcamp/cocoon-vanilla-js'></script>
or
<%= javascript_include_tag 'https://cdn.jsdelivr.net/npm/@oddcamp/cocoon-vanilla-js@1.1.3/index.min.js' %>

ちなみに公式だと

yarn add @oddcamp/cocoon-vanilla-js

が推奨されている。

model

Post

class Post < ApplicationRecord
  has_many :genres, dependent: :destroy
  accepts_nested_attributes_for :genres, allow_destroy: true
end

Genre

class Genre < ApplicationRecord
  belongs_to :post
end

accepts_nested_attributes_for

accepts_nested_attributes_forを使用することで、指定したモデルのデータを配列としてパラメーターに含めることができる。
引用元

controller

子モデルも作成してあげること、子モデルもパラメーターとして受け取ってあげること。

class PostsController < ApplicationController

  def new
    @post = Post.new
    //子モデルも作成してあげる
    @post.genres.build
  end

  def create
    @post = Post.new(post_params)
    if @post.save
      redirect_to 
    else
      render :new
    end
  end

  private

  def recipe_params
    params.require(:recipe).permit(:title, 
                                   :content, 
                                   //子モデルもパラメーターとして受け取ってあげる
                                   genres_attributes: [:name]
                                   )
  end
end

view

子モデルのgenreの部分のみ抜粋。

// フォームの追加ボタン
<%= link_to_add_association '追加' %>

// 追加ボタンを押すと、以下が複製されていく
<%= form.fields_for :genres do | genre | %>
 <%= genre.file_field :name %>
 // フォームの削除ボタン
 <%= link_to_remove_association '削除' %>
<% end %>
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1