お世話になっております。
下記サイト様のモデル設計を参考にして、ユーザー新規登録時の入力フォーム経由でUser、Group(中間テーブル)、Familyの複数モデルで同時にデータ保存できるようにしたいです。
参考サイト様
https://qiita.com/tak8_al/items/08274dd9228363642555
またデータ保存をしたい各モデルの内容は下記の通りです。
・Userモデル
- id
- name
- password_digest
・Groupモデル(中間テーブル)
- id
- family_id
- user_id
・Familyモデル
- name
初歩的な質問をしてしまい大変恐縮ですが、ご助言いただけますと幸いです。
どうぞよろしくお願いいたします。
実現したいこと
- ユーザー新規登録時に、Group、Familyモデルのデータ保存が同時に行えるようにしたい
前提
前提として家族で育児記録を共有できる仕様にしたいと考え、家族関係にあるユーザーを紐づけるべく、中間テーブルとしてGroupモデルを作成しました。
また参考サイト様ではFamilyモデルを用意してのちにFamilyモデルとPetモデル(私の場合ではChildモデル予定)を紐づけるデータベース設計だったので、新たにFamilyモデルを追加しました。
しかし中間テーブルを含めた複数モデルでのデータ保存の方法を今ひとつ理解できておらず、質問させていただきました。
【追記】
コメントにて参考サイトの情報が古く理解の妨げになるとのご指摘をいただきまして、参考サイト様をRailsガイドへと変更させていただきました。
発生している問題・エラーメッセージ
コンソール上でUnpermitted parameters: :user_id, :group, :family.とあることからストロングパラメータ内の問題と理解しましたが、どのように変更すればいいのかがわかっておりません。
またfamily_idというGroupモデルの外部キーをどのように取得すればいいのか、入力フォームでの取り方自体がまず間違っている点も問題だと考えております。
terminal
1Started POST "/admin/users" for ::1 at 2023-09-29 13:46:35 +0900 2Processing by Admin::UsersController#create as TURBO_STREAM 3 Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"name"=>"ユーザーF", "email"=>"f@example.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "user_id"=>"1", "group"=>{"group_id"=>""}, "family"=>{"name"=>"サンプル"}}, "commit"=>"登録する"} 4 5Unpermitted parameters: :user_id, :group, :family. Context: { controller: Admin::UsersController, action: create, request: #<ActionDispatch::Request:0x000000010dc2ec38>, params: {"authenticity_token"=>"[FILTERED]", "user"=>{"name"=>"ユーザーF", "email"=>"f@example.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "user_id"=>"1", "group"=>{"group_id"=>""}, "family"=>{"name"=>"サンプル"}}, "commit"=>"登録する", "controller"=>"admin/users", "action"=>"create"} } 6 TRANSACTION (0.1ms) BEGIN 7 ↳ app/controllers/admin/users_controller.rb:15:in `create' 8 User Exists? (0.7ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "f@example.com"], ["LIMIT", 1]] 9 ↳ app/controllers/admin/users_controller.rb:15:in `create' 10 11 TRANSACTION (0.1ms) ROLLBACK 12 ↳ app/controllers/admin/users_controller.rb:15:in `create' 13 Rendering layout layouts/application.html.slim 14 Rendering admin/users/new.html.slim within layouts/application 15 User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 16 ↳ app/controllers/application_controller.rb:8:in `current_user' 17 Rendered admin/users/_form.html.slim (Duration: 2.5ms | Allocations: 6987) 18 Rendered admin/users/new.html.slim within layouts/application (Duration: 2.6ms | Allocations: 7176) 19 CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 20 ↳ app/controllers/application_controller.rb:8:in `current_user' 21 Rendered layout layouts/application.html.slim (Duration: 5.9ms | Allocations: 14075) 22Completed 422 Unprocessable Entity in 312ms (Views: 5.9ms | ActiveRecord: 10.4ms | Allocations: 30071)
該当のソースコード
【追記】参考サイト様の情報をもとに主にコントローラ周りを編集しましたが、バリデーションによるエラーメッセージとして、Groups familyを入力してくださいとusers#newビュー画面上に表示されている状況です。
各種モデルアソシエーション設定
app/models/famiry.rb
1class Family < ApplicationRecord 2 has_many :groups, dependent: :destroy 3 has_many :users, through: :groups, source: :user 4end
app/models/group.rb
1class Group < ApplicationRecord 2 belongs_to :family 3 belongs_to :user 4end
【追加】userモデル内に、Familyモデルに関するaccepts_nested_attributes_forの設定を追記しました。
app/models/user.rb
1class User < ApplicationRecord 2 has_many :groups, dependent: :destroy 3 has_many :families, through: :groups, source: :family 4 accepts_nested_attributes_for :groups, allow_destroy: true 5 accepts_nested_attributes_for :families, allow_destroy: true 6end
usersコントローラ
【追加】ストロングパラメータ内設定を変更しました。
app/controllers/users_controller.rb
1def create 2 @user = User.new(user_params) 3 @user.groups.build 4 5 if @user.save 6 redirect_to root_path, notice: "「#{@user.name}」さんを登録しました" 7 else 8 render :new, status: :unprocessable_entity 9 end 10end 11 12private 13 14 def user_params 15 params.require(:user).permit(:name, :email, :password, :password_confirmation, groups_attributes: [:id, :user_id, :family_id], families_attributes: [:id, :name]) 16 end
ユーザー新規登録時入力フォームビュー
【追加】ネストした入力フォームのGroupモデルに関するhidden_field設定を変更しました。
app/views/admin/users/_form.html.slim
1= form_with model: @user, url: admin_users_url, local: true do |f| 2 3 .form-group 4 = f.label :name 5 = f.text_field :name, class: 'form-control' 6 7 .form-group 8 = f.label :email 9 = f.text_field :email, class: 'form-control' 10 11 .form-group 12 = f.label :password 13 = f.password_field :password, class: 'form-control' 14 15 .form-group 16 = f.label :password_confirmation 17 = f.password_field :password_confirmation, class: 'form-control' 18 19 = f.hidden_field :user_id, :value => current_user.id 20 21 = f.fields_for :group do |g| 22 = g.hidden_field :family_id 23 24 = f.fields_for :family do |ff| 25 = ff.label :name 26 = ff.text_field :name 27 28 = f.submit '登録する', class: 'btn btn-primary'
試したこと
- accepts_nested_attributes_forによる複数モデルのデータ保存
- fields_for使用での入力フォームのネスト
- 各モデルのアソシエーション見直し
補足情報(FW/ツールのバージョンなど)
- ruby 3.1.2p20
- Rails 7.0.6
回答1件
あなたの回答
tips
プレビュー