前提・実現したいこと
概要
Ruby(Ruby on Rails)で自身と相手で連絡が可能なアプリを作成しています。
(自身と任意の別ユーザーのプロジェクト(連絡板)を作成し、その中で連絡をとることができる機能)
その中で実現したいことは、
プロジェクトを新規作成した際に、中間テーブルに外部キーであるuser_id、project_idを併せて保存する
ということですがこの点で先へ進めない状態となっています。
設定背景
モデル :user、project、pro_user(左記テーブルの中間テーブル)
導入したgem:devise(ユーザー管理)、pry-rails
発生している問題・エラーメッセージ
発生している問題
- binding.pryでプロセスを止めフォームから送られたparamsの内容を確認。projectsテーブル及びpro_userテーブルへの保存に必要なデータ(プロジェクト名及びuser_id)は含まれていることをターミナル上で確認。
- 上記を確認した後、saveメソッドで保存の可否をターミナル上で確認したところ、以下のターミナルの表示通りでROLLBACKがされ保存できない状況となった。
エラーメッセージ
6: def create 7: @project = Project.new(project_params) => 8: binding.pry 9: if @project.save 10: redirect_to root_path 11: else 12: render :new 13: end 14: end [1] pry(#<ProjectsController>)> @project.save (0.4ms) BEGIN ↳ (pry):1:in `create' User Exists? (0.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 't@t' AND `users`.`id` != 1 LIMIT 1 ↳ (pry):1:in `create' User Exists? (0.6ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 's@s' AND `users`.`id` != 2 LIMIT 1 ↳ (pry):1:in `create' (0.2ms) ROLLBACK ↳ (pry):1:in `create' => false
お伺いしたいこと
原因と考えられる点やアクションプランがあればご助言いただきたく存じます。
- 以下に記述している試したこと(ターミナル上での原因探索等)を踏まえ、ビューファイルの記述不備が根本原因ではなく、モデルやデータベースに何らかの不備があると推測しています
- しかし、知識不足ゆえに確実な根本原因と言い切れないこと、また対策のアクションプランが手詰まりであるため、今回質問をさせていただきました。
該当のソースコード
routes.rb
Ruby
1Rails.application.routes.draw do 2 devise_for :users 3 root to: 'messages#index' 4 resources :projects, only: [:new, :create] 5end
projects_controller.rb
Ruby
1class ProjectsController < ApplicationController 2 def new 3 @project = Project.new 4 end 5 6 def create 7 @project = Project.new(project_params) 8 if @project.save 9 redirect_to root_path 10 else 11 render :new 12 end 13 end 14 15 private 16 17 def project_params 18 params.require(:project).permit(:name, user_ids:[]) 19 end 20end
models > user.rb
Ruby
1class User < ApplicationRecord 2 #アソシエーションを抜粋 3 has_many :pro_users 4 has_many :projects, through: :pro_users 5end
models > project.rb
Ruby
1class Project < ApplicationRecord 2 #アソシエーションを抜粋 3 has_many :pro_users 4 has_many :users, through: :pro_users, dependent: :destroy 5end
models > pro_user.rb
Ruby
1class ProUser < ApplicationRecord 2 belongs_to :user 3 belongs_to :project 4end
試したこと
- ターミナルでのエラー原因探索(★情報追加依頼の方にお示しした箇所)
[1][4][5]で示されている通り、user_idをもとにusersテーブルからデータの取得ができていないことが原因と考えられる
[2] pry(#<ProjectsController>)> params => <ActionController::Parameters {"authenticity_token"=>"gE3lWZX40UGHzTvg/BkYV2WqROr6GK/QpV1PE6XHuqJUpauKuzxCY35jNKBKDOGVZJdKJVNlMu7KdRLttHWmkA==", "project"=><ActionController::Parameters {"name"=>"お試し", "user_ids"=>["1", "2"]} permitted: false>, "commit"=>"Create Project", "controller"=>"projects", "action"=>"create"} permitted: false> [3] pry(#<ProjectsController>)> project_params => <ActionController::Parameters {"name"=>"お試し", "user_ids"=>["1", "2"]} permitted: true> [4] pry(#<ProjectsController>)> @project.errors => #<ActiveModel::Errors:0x00007fed1b9ac328 @base=#<Project:0x00007fed1431d5b8 id: nil, name: "お試し", created_at: nil, updated_at: nil>, @details={:users=>[{:error=>:invalid}, {:error=>:invalid}]}, @messages={:users=>["is invalid"]}> [5] pry(#<ProjectsController>)> @project.errors.full_messages => ["Users is invalid"]
- rails db:migrateの不備を疑う(カラムの型や外部キー設定に不備)
改めてrails db:migrate:resetを実行→以下の通り設定ができているものの結果は変わらず
+------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | user_id | bigint(20) | YES | MUL | NULL | | | project_id | bigint(20) | YES | MUL | NULL | | | created_at | datetime(6) | NO | | NULL | | | updated_at | datetime(6) | NO | | NULL | | +------------+-------------+------+-----+---------+----------------+
- user_idsという配列のパラメータが複数あることが原因と仮定
ビューファイルをい1行コメントアウトすることで、現在のユーザーidがパラメータに含まれないようにしてから実行
→試行前と同じエラーが出現したため配列内のパラメータ数は根本原因ではない可能性が高いことが推測された
ERB
1<div class='project-form__field--right'> 2 <select name='project[user_ids][]'> 3 <option value=''>アサインメンバーを選択してください</option> 4 <% User.all.where.not(id: current_user.id). each do |user| %> 5 <option value=<%=user.id%>><%= user.last_name %><%= user.first_name %></option> 6 <% end %> 7 </select> 8 #以下の1行をコメントアウト 9 <input name='project[user_ids][]' type='hidden' value=<%=current_user.id>> 10</div>
####試したことの追記(2020/9/4)
- if @prject.save!(@prject.errors)により、User is invalid がエラー内容として出現していたことから、Validationが邪魔をしているため保存ができていないことを疑った
→UserモデルのValidationを一時的にコメントアウトした結果、意図したデータ保存がされた(プロジェクトと同時に中間テーブルのデータも保存)
→根本原因はValidationであることが判明した。しかし、ValidationはUser登録の時に必須でありコンフリクトが生じてしまった。
Ruby
1class User < ApplicationRecord 2 # Include default devise modules. Others available are: 3 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 4 devise :database_authenticatable, :registerable, 5 :recoverable, :rememberable, :validatable 6 7 # japanese_letters = /\A[ぁ-んァ-ン一-龥]+\z/ 8 # with_options presence: true do 9 # validates :last_name, format: { with: japanese_letters, message: 'is not full-width characters' } 10 # validates :first_name, format: { with: japanese_letters, message: 'is not full-width characters' } 11 # validates :email, uniqueness: { case_sensitive: true }, 12 # format: { with: /\w+([-+.]\w+)*@\w+([-.]\w+)*/ } 13 # validates :password, length: {minimum: 6 }, 14 # format: { with: /\A(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]+\z/, message: 'includes both half-width letters and half-width numbers' } 15 # validates :company, :password_confirmation 16 # end 17 18 has_many :pro_users 19 has_many :projects, through: :pro_users 20 has_many :messages 21end
ターミナル
Parameters: {"authenticity_token"=>"ZOq+q72nyTZK7+6DAc1vIWclC/OS2UauGGAJ+BjjsUWwAvB4k2NaFLNB4cO32JbjZhgFPDuk25B3SFQGCVGtdw==", "project"=>{"name"=>"お試し", "user_ids"=>["1", "2"]}, "commit"=>"Create Project"} User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ORDER BY `users`.`id` ASC LIMIT 1 User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1, 2) ↳ app/controllers/projects_controller.rb:7:in `create' (0.2ms) BEGIN ↳ app/controllers/projects_controller.rb:8:in `create' Project Create (0.9ms) INSERT INTO `projects` (`name`, `created_at`, `updated_at`) VALUES ('お試し', '2020-09-04 05:43:52.654047', '2020-09-04 05:43:52.654047') ↳ app/controllers/projects_controller.rb:8:in `create' ProUser Create (0.2ms) INSERT INTO `pro_users` (`user_id`, `project_id`, `created_at`, `updated_at`) VALUES (1, 4, '2020-09-04 05:43:52.657678', '2020-09-04 05:43:52.657678') ↳ app/controllers/projects_controller.rb:8:in `create' ProUser Create (0.2ms) INSERT INTO `pro_users` (`user_id`, `project_id`, `created_at`, `updated_at`) VALUES (2, 4, '2020-09-04 05:43:52.659268', '2020-09-04 05:43:52.659268') ↳ app/controllers/projects_controller.rb:8:in `create' (0.6ms) COMMIT
補足情報(FW/ツールのバージョンなど)
- ruby '2.6.5'
- rails (6.0.3.2)
以上、よろしくお願いいたします。
回答2件
あなたの回答
tips
プレビュー