Rails 多対多テーブル構造をcollection_check_boxesで関連付ける
formを用いた際の多対多テーブルの関連付けを、collection_check_boxesを使用して行う。
テーブル構造
create_table "users", force: :cascade do |t| t.string "name" t.datetime "created_at" t.datetime "updated_at" end create_table "services", force: :cascade do |t| t.string "name" t.datetime "created_at" t.datetime "updated_at" end create_table "users_services", force: :cascade do |t| t.integer "user_id" t.integer "service_id" t.datetime "created_at" t.datetime "updated_at" end
モデル
class User < ApplicationRecord has_many :users_services has_many :services, through: :users_services end
class Service < ApplicationRecord has_many :users_services has_many :users, through: :users_services end
class UsersService < ApplicationRecord belongs_to :user belongs_to :service end
コントローラー
class UsersController < ApplicationController def new @user = User.new @services = Service.all end def create user = User.new(permit_params) user.save! end private def permit_params params.require(:user).permit(:name, service_ids: []) end end
User
モデルの service_ids
メソッドに対して値を送信できるようにビューの定義を行う。
ビュー
※slim構文にて定義
= form_with scope: :user, mdoel: @user, url: users_path do |form| = form.text_field :name = form.collection_check_boxes :service_ids, @services, :id, :name, include_hidden: false = form.submit 'post'
collection_check_boxes
が services
テーブルに登録したレコードのID・名称を展開して表示を行う。
include_hidden
は空白文字をhiddenで定義するかオプションで設定を変更できる(不要なので今回はfalse)。
任意の内容で入力を行いsubmitすると、関連も含めてレコードを保存できる。
web_1 | Started POST "/users" for 172.18.0.1 at 2023-05-03 07:46:45 +0000 web_1 | Cannot render console from 172.18.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1 web_1 | Processing by UsersController#create as TURBO_STREAM web_1 | Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"name"=>"test", "service_ids"=>["1", "2"]}, "commit"=>"post"} web_1 | Service Load (0.3ms) SELECT `services`.* FROM `services` WHERE `services`.`id` IN (1, 2) web_1 | ↳ app/controllers/users_controller.rb:8:in `create' web_1 | TRANSACTION (0.2ms) BEGIN web_1 | ↳ app/controllers/users_controller.rb:9:in `create' web_1 | User Create (0.7ms) INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('test', '2023-05-03 07:46:45.726583', '2023-05-03 07:46:45.726583') web_1 | ↳ app/controllers/users_controller.rb:9:in `create' web_1 | UsersService Create (0.6ms) INSERT INTO `users_services` (`user_id`, `service_id`, `created_at`, `updated_at`) VALUES (1, 1, '2023-05-03 07:46:45.730791', '2023-05-03 07:46:45.730791') web_1 | ↳ app/controllers/users_controller.rb:9:in `create' web_1 | UsersService Create (0.2ms) INSERT INTO `users_services` (`user_id`, `service_id`, `created_at`, `updated_at`) VALUES (1, 2, '2023-05-03 07:46:45.732966', '2023-05-03 07:46:45.732966') web_1 | ↳ app/controllers/users_controller.rb:9:in `create' web_1 | TRANSACTION (7.5ms) COMMIT web_1 | ↳ app/controllers/users_controller.rb:9:in `create' web_1 | No template found for UsersController#create, rendering head :no_content web_1 | Completed 204 No Content in 60ms (ActiveRecord: 10.1ms | Allocations: 11039)