前提・実現したいこと
Ruby on Railsでチャットアプリのようなものを作っています。
現在は複数ユーザーを含めたチャットルームの生成機能を実装しようとしています。
発生している問題・エラーメッセージ
チャットルームを作成するために、
- usersテーブル(devise使用)
- roomsテーブル ※チャットルームのためのテーブル
- room_usersテーブル(中間テーブル)
を準備し、いざチャットルームを作成しようとすると、Users is invalid
とエラーメッセージが吐き出され、ルームの新規作成ができない状態です。
該当のソースコード
model
Ruby
1# Userモデル 2class User < ApplicationRecord 3 extend ActiveHash::Associations::ActiveRecordExtensions 4 # Include default devise modules. Others available are: 5 # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 6 devise :database_authenticatable, :registerable, 7 :recoverable, :rememberable, :validatable 8 PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i.freeze 9 validates_format_of :password, with: PASSWORD_REGEX, message: 'include both letters and numbers' 10 with_options presence: true do 11 validates :nickname 12 validates :birthday 13 end 14 with_options numericality: { other_than: 1, message: 'must be chosen'} do 15 validates :study_genre_id 16 end 17 validates :email, uniqueness: { case_sensitive: false } 18 19 has_many :room_users 20 has_many :rooms, through: :room_users 21 belongs_to_active_hash :study_genre 22 23end 24
Ruby
1# roomモデル 2class Room < ApplicationRecord 3 has_many :room_users 4 has_many :users, through: :room_users 5 has_one_attached :image 6 validates :title, presence: true 7end
Ruby
1# room user モデル 2class RoomUser < ApplicationRecord 3 belongs_to :room 4 belongs_to :user 5end
####view
HTML
1<div class="registration-body"> 2 <%= form_with model: @room, url: rooms_path(@room), class: 'registration-main', local: true do |f| %> 3 <div class='form-wrap'> 4 <div class='form-header'> 5 <h1 class='form-header-text'> 6 学習報告ルームの情報を入力 7 </h1> 8 </div> 9 10 <%= render 'shared/error_messages', model: f.object %> 11 12 <div class="form-group"> 13 <div class='form-text-wrap'> 14 <label class="form-text">ルーム画像</label> 15 </div> 16 <div class="click-upload"> 17 <p> 18 クリックしてファイルをアップロード 19 </p> 20 <%= f.file_field :image, class:"room-image" %> 21 </div> 22 </div> 23 24 <div class="form-group"> 25 <div class='form-text-wrap'> 26 <%= f.label :title, "ルーム名", class:"form-text" %> 27 <span class="indispensable">必須</span> 28 </div> 29 <%= f.text_area :title, class:"input-default", placeholder:"例) rails勉強会", maxlength:"40" %> 30 </div> 31 <div class="form-group"> 32 <div class='form-text-wrap'> 33 <%= f.label :purpose_room, "この学習報告ルームの目的", class:"form-text" %> 34 <span class="indispensable">※140字まで</span> 35 </div> 36 <%= f.text_area :purpose_room, class:"input-introduction", placeholder:"ルームの説明(学習テーマ、目的、学習目標等)例) Ruby on Railsの学習報告ルームです。webエンジニアを目指して学習を行っていきましょう。平日2時間、休日8時間学習しましょう", maxlength:"140" %> 37 </div> 38 <div class="form-group"> 39 <div class='form-text-wrap'> 40 <label class="form-text">メンバーを選択してください</label> 41 <span class="indispensable">必須</span> 42 </div> 43 <select name="room[user_ids][]" > 44 <option value="">ユーザーを選択してください</option> 45 <% User.where.not(id: current_user.id).each do |user| %> 46 <option value=<%= user.id %>><%= user.nickname %></option> 47 <% end %> 48 </select> 49 <!-- これで現在ログインしているユーザーの情報も含められる --> 50 <input name="room[user_ids][]" type="hidden" value=<%= current_user.id %>> 51 </div> 52 53 54 <div class="form-group"> 55 <h2 class='form-bottom-text'> 56 「ルーム作成」ボタンを押すと、学習報告ルームが生成されます。 57 </h2> 58 </div> 59 <div class='register-btn'> 60 <%= f.submit "ルーム作成" ,class:"register-link" %> 61 </div> 62 </div> 63 <% end %> 64</div>
controller
Ruby
1# applicationコントローラー 2class ApplicationController < ActionController::Base 3 before_action :authenticate_user! 4 before_action :configure_permitted_parameters, if: :devise_controller? 5 6 private 7 8 def configure_permitted_parameters 9 devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :birthday, :study_genre_id, :self_introduction]) 10 end 11end
Ruby
1# rooms コントローラー 2class RoomsController < ApplicationController 3 before_action :authenticate_user!, only:[:index] 4 5 def index 6 end 7 8 def new 9 @room = Room.new 10 end 11 12 def create 13 @room = Room.new(room_params) 14 if @room.save 15 redirect_to root_path 16 else 17 render :new 18 end 19 end 20 21 private 22 23 def room_params 24 params.require(:room).permit(:image, :title, :purpose_room, user_ids: []) 25 end 26 27end 28
試したこと
まず、ちゃんと@roomを作成するにあたりパラメーターが送られているか確認するため、コントローラーにbinding.pry
を追記して検証しました。
すると
# ターミナル [1] pry(#<RoomsController>)> params => <ActionController::Parameters {"authenticity_token"=>"r1SvQ8cy9JigppFTk5G6mG/OYUM61AbFq0Rhl1kD2Sy42j5nSh6vNU0juvffGnJIPlwRd5vjzC47N4FhNmOMYA==", "room"=> <ActionController::Parameters {"image"=>#<ActionDispatch::Http::UploadedFile:0x00007fb29901ffb0 @tempfile=# <Tempfile:/var/folders/dt/2sln7kx14rl51gk_97gkhj2m0000gn/T/RackMultipart20210109-26266-qu1y9u.png>, @original_filename="arrow_top.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"room[image]\"; filename=\"arrow_top.png\"\r\nContent-Type: image/png\r\n">, "title"=>"test", "purpose_room"=>"test", "user_ids"=>["2", "1"]} permitted: false>, "commit"=>"ルーム作成", "controller"=>"rooms", "action"=>"create"} permitted: false>
ということで、受け取れているようです。
そこで@room.save
を行うと、以下の通り、
# ターミナル [2] pry(#<RoomsController>)> @room.save (0.2ms) BEGIN ↳ (pry):2:in `create' User Exists? (0.3ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = 'tester@com' AND `users`.`id` != 2 LIMIT 1 ↳ (pry):2:in `create' User Exists? (0.3ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = 'test@test.com' AND `users`.`id` != 1 LIMIT 1 ↳ (pry):2:in `create' (0.2ms) ROLLBACK ↳ (pry):2:in `create' => false
と出てきており、saveがうまくいっていないようです。(rollbackされている)
そこで、過去質問されていた記事(https://teratail.com/questions/196445)を参考に、中間テーブルを
Ruby
1class RoomUser < ApplicationRecord 2 # optional: true を追記 3 belongs_to :room, optional: true 4 belongs_to :user, optional: true 5end 6
としましたが、結果は変わらず。
また、userモデルのemailのuniquenessが邪魔しているのでは?という記事も見かけた(リンクは見失いました、、)ので試してみると、
# ターミナル [1] pry(#<RoomsController>)> @room.save => false
幾分淡白に、、@room.save!
を試すと、
# ターミナル [2] pry(#<RoomsController>)> @room.save! ActiveRecord::RecordInvalid: Validation failed: Users is invalid from /Users/yajimaryoga/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-6.0.3.4/lib/active_record/validations.rb:80:in `raise_validation_error'
結局、抜け出せない状態です、、
環境
- Ruby: 2.6.5
- Rails: 6.0.3.4
- ユーザー登録: devise
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/09 11:09
2021/01/09 12:44