【Rails】collection_check_boxesで多対多の関連付けをする方法

やりたいこと

UserテーブルとLessonテーブルの関係を表したER図

  • 上のようなテーブル構成
    • UserテーブルとLessonテーブルは多対多の関係
    • 1人のユーザーは複数のLessonを履修している
  • User登録時、チェックボックスで選択したLessonとそのUserを結びつけたい
  • モデルからチェックボックスを自動生成したい

解決法

collection_check_boxesというビューヘルパーメソッドを使う。

<%= form_for @user,url:admin_users_path do |form| %>
<%= form.collection_check_boxes(:lesson_ids, @lessons, :id, :name) do |lesson| %>
<%= lesson.check_box %>
<%= lesson.text %>
<% end %>
<% end %>

今回の例の場合、上記のようにすることでLessonテーブルのレコードに応じてチェックボックスが生成される。

実装例

環境

  • Ruby 2.6.5
  • Rails 5.2.4.3

モデル

class User < ApplicationRecord
has_secure_password
has_many :take_lessons,dependent: :destroy
has_many :lessons,through: :take_lessons
end
class Lesson < ApplicationRecord
has_many :take_lessons,dependent: :destroy
has_many :users,through: :take_lessons
end
class TakeLesson < ApplicationRecord
belongs_to :user
belongs_to :lesson
end

コントローラ

class Admin::UsersController < Admin::Base
def new
@user = User.new
@lessons = Lesson.all
end
def create
@user=User.new(user_params)
@user.admin=false
@lesson_ids=params[:user][:lesson_ids]
@lesson_ids.shift
if @user.save
@lesson_ids.each do |lesson_id|
lesson = Lesson.find(lesson_id.to_i)
@user.lessons << lesson #関連付ける
end
flash[:notice] = "生徒を追加しました"
redirect_to("/admin/users")
else
flash[:notice] = "生徒を追加できませんでした"
redirect_to("/admin/users/new")
end
end
def user_params
params.require(:user).permit(:name, :faculty, :grade, :student_id, :password, :password_confirmation)
end
end

ビュー

<h2>ユーザー追加</h2>
<%= form_for @user,url:admin_users_path do |form| %>
<%= form.collection_check_boxes(:lesson_ids, @lessons, :id, :name) do |lesson| %>
<ul>
<li>
<%= lesson.check_box %>
<%= lesson.text %>
</li>
</ul>
<%end%>
<%= form.submit("追加する") %>
<%end%>

1

参考
  1. collection_check_boxes | Railsドキュメント