前提・実現したいこと
チャット機能のあるアプリを作成しています。
問題はroomsテーブルの保存時にusersのバリデーションにより保存できないという点です。
roomsテーブルとusersテーブルは中間テーブル(room_users)を挟んだ多対多の関係にあります。
usersの保存時には特に問題なく保存でき、バリデーションによる制限も意図した動作をしてくれます。(passwordに半角英数混合を強制させ、そのように動作します。)
usersのバリデーションを動作させた上でroomsを保存したいのですが、どのようにすれば解決できますでしょうか。ご教授お願い致します。
発生している問題・エラーメッセージ
バリデーションに失敗しました: Usersは不正な値です
該当のソースコード
■views/rooms/new.html.erb
html
1<div class="contents"> 2 <div class="main"> 3 <%= render "tasks/header"%> 4 <%= form_with model:@room, local: true do |f|%> 5 <div class="center"> 6 <div class="room-builder"> 7 <div class="user-selector"> 8 <div class="user-seach"> 9 ①相談する相手を選択してください 10 </div> 11 <div class="user-scroll"> 12 <% User.all.where.not(id: current_user.id).each do |user|%> 13 <div class="user-bar" data-name=<%= user.nickname%> data-id=<%= user.id%>> 14 <%= user.nickname%> 15 </div> 16 <% end %> 17 </div> 18 </div> 19 <div class="room-form"> 20 <div class="user-confirmation" name="room[user_ids][]"> 21 ②相談する相手はこの方でよろしいですか? 22 <div class='user-confirmation-bar'> 23 </div> 24 <input name="room[user_ids][]" type="hidden" value=<%= current_user.id %>> 25 <%# ユーザーがクリックした.user-barのdata-idをJavaScriptの操作で下記select-userのvalueにしています。 %> 26 <input name="room[user_ids][]" type="hidden" class="select-user"> 27 </div> 28 <div class="room-name"> 29 ③ルーム名を入力してください。<br> 30 何についての相談かがわかるような名前にしましょう。<br> 31 例)次の会議の予定はいつ?<br> 32 <%= f.text_field :room_name, class:'room-name-input', placeholder: 'ルーム名を入力してください'%> 33 </div> 34 <div class="instructions"> 35 ④入力が出来たら『ルーム作成』ボタンを押してルームを作成しましょう。 36 </div> 37 </div> 38 </div> 39 <% if @room.errors.any? %> 40 <div class="error-alert"> 41 <ul> 42 <% @room.errors.full_messages.each do |message| %> 43 <li class='error-message'><%= message %></li> 44 <% end %> 45 </ul> 46 </div> 47 <% end %> 48 </div> 49 <div class="footer"> 50 <%=f.submit 'ルーム作成', class:"add-task-btn" %> 51 </div> 52 <% end %> 53 </div> 54 <%= render "tasks/side"%> 55</div>
■models/user.rb
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 has_many :room_users, dependent: :destroy 7 has_many :rooms, through: :room_users, dependent: :destroy 8 has_many :tasks, dependent: :destroy 9 10 11 validates :nickname, presence: true, length: {in: 1..12 } 12 13 # 問題のバリデーションです。下2行をコメントアウトすると正常に保存できます。 14 PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i.freeze 15 validates_format_of :password, with: PASSWORD_REGEX, message: 'は半角英数混合で入力して下さい' 16end
■models/room.rb
ruby
1class Room < ApplicationRecord 2 has_many :room_users, dependent: :destroy 3 has_many :users, through: :room_users 4 has_many :problems, dependent: :destroy 5 6 validates :room_name, presence: true, length: {in: 1..10 } 7end
■models/room_user.rb
ruby
1class RoomUser < ApplicationRecord 2 belongs_to :user 3 belongs_to :room 4end
試したこと
①user.rbの問題のバリデーションをコメントアウト→rooms、room_users共に正常に保存可能。(勿論usersにはバリデーションがかかっていない)
②user.rbの問題のバリデーションを一意性制約に変更→rooms、room_users共に同様のエラーにより保存されず。
③バリデーションをかけた上でusersの保存→保存可能。バリデーションはpasswordを英数混合に指定する事を意図しているが、その通りに動作する。
④roomsのcreateアクションにてbinding.pryを仕込んでみる。→paramsは意図した通りのパラメーターを送っている。
From: /Users/kintarou/projects/good-question/app/controllers/rooms_controller.rb:9 RoomsController#create: 7: def create 8: @room = Room.new(room_params) => 9: binding.pry 10: if @room.save 11: redirect_to root_path 12: else 13: render :new 14: end 15: end [1] pry(#<RoomsController>)> @room => #<Room:0x00007f843bdd0330 id: nil, room_name: "次の会議の予定", created_at: nil, updated_at: nil> [2] pry(#<RoomsController>)> Started GET "/cable" for ::1 at 2020-11-10 14:42:27 +0900 [2] pry(#<RoomsController>)> params => <ActionController::Parameters {"authenticity_token"=>"lqTqiP2G7lc/kKrguWt7DrNNPPYgsAcX4ISbx/kvFe51zWC+PUvWDr6TOdDTn9HHphM1zm1eAQxrvS5gHKXaKQ==", "room"=><ActionController::Parameters {"user_ids"=>["1", "2"], "room_name"=>"次の会議の予定"} permitted: false>, "commit"=>"ルーム作成", "controller"=>"rooms", "action"=>"create"} permitted: false> [3] pry(#<RoomsController>)> @room.save! ActiveRecord::RecordInvalid: バリデーションに失敗しました: Usersは不正な値です from /Users/kintarou/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-6.0.3.3/lib/active_record/validations.rb:80:in `raise_validation_error' [4] pry(#<RoomsController>)>
⑤サーバー再起動・PC再起動→状況変わらず。
補足情報(FW/ツールのバージョンなど)
Rails 6.0.3.3
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin19]
初めての質問で要領を得ない事、足りない情報あるかもしれませんが、ご容赦ください。
併せてご教授頂ければ幸いです。
よろしくお願い致します。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/10 10:06
2020/11/10 10:33