前提・実現したいこと
プログラミング初心者で初投稿です。何卒よろしくお願いします。
Deviseを使い、User(ユーザー)モデルとConcierge(管理者)モデル間でActionCableを用いリアルタイムチャット機能を実装しています。
チャット入力フォームに文章を入力するも、反映されず、ターミナル上で下記エラーがでてしまいます。
Createアクション、Showアクションでチャットルーム自体は作成、ページに変遷は可能ですが、
チャット入力フォームに文章を入力するも、反映されず、ターミナル上で下記エラーがでてしまいます。
発生している問題・エラーメッセージ
Parameters: {"id"=>"14"} User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ORDER BY `users`.`id` ASC LIMIT 1 ChatRoom Load (1.1ms) SELECT `chat_rooms`.* FROM `chat_rooms` WHERE `chat_rooms`.`id` = 14 LIMIT 1 ↳ app/controllers/chat_rooms_controller.rb:15:in `show' (0.4ms) SELECT `chat_room_users`.`concierge_id` FROM `chat_room_users` WHERE `chat_room_users`.`chat_room_id` = 14 ↳ app/controllers/chat_rooms_controller.rb:16:in `show' Concierge Load (0.6ms) SELECT `concierges`.* FROM `concierges` WHERE `concierges`.`id` = 4 LIMIT 1 ↳ app/controllers/chat_rooms_controller.rb:17:in `show' Rendering chat_rooms/show.html.erb within layouts/application ChatMessage Load (3.2ms) SELECT `chat_messages`.* FROM `chat_messages` WHERE `chat_messages`.`chat_room_id` = 14 ↳ app/views/chat_rooms/show.html.erb:4 Rendered collection of templates [0 times] (Duration: 0.0ms | Allocations: 3) Rendered chat_rooms/show.html.erb within layouts/application (Duration: 8.0ms | Allocations: 917) [Webpacker] Everything's up-to-date. Nothing to do Completed 200 OK in 126ms (Views: 103.4ms | ActiveRecord: 5.8ms | Allocations: 17564) Started GET "/cable" for ::1 at 2021-06-06 16:27:20 +0900 Started GET "/cable/" [WebSocket] for ::1 at 2021-06-06 16:27:20 +0900 Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket) An unauthorized connection attempt was rejected Finished "/cable/" [WebSocket] for ::1 at 2021-06-06 16:27:20 +0900
該当のソースコード
Ruby
1class ChatRoomsController < ApplicationController 2 before_action :authenticate_user! 3 4 def create 5 current_user_chat_rooms = ChatRoomUser.where(user_id: current_user.id).map(&:chat_room) 6 chat_room = ChatRoomUser.where(chat_room: current_user_chat_rooms, concierge_id: params[:concierge_id]).map(&:chat_room).first 7 if chat_room.blank? 8 chat_room = ChatRoom.create 9 ChatRoomUser.create(chat_room: chat_room, user_id: current_user.id, concierge_id: params[:concierge_id]) 10 end 11 redirect_to action: :show, id: chat_room.id 12 end 13 14 def show 15 @chat_room = ChatRoom.find(params[:id]) 16 chat_room_user = @chat_room.chat_room_users.pluck(:concierge_id).first 17 @chat_room_user = Concierge.find_by(id: chat_room_user) 18 @chat_messages = ChatMessage.where(chat_room: @chat_room) 19 end 20 21end 22
Ruby
1<p>チャットルームページ</p> 2 3<div id='chat-messages'> 4 <%= render @chat_messages %> 5</div> 6 7<form> 8 <textarea data-behavior="chat_room_speaker" data-chat_room_id="<%= @chat_room.id %>" placeholder="メッセージを入力" class="chat-room__message-form_textarea"></textarea> 9</form> 10 11
Ruby
1module ApplicationCable 2 class Connection < ActionCable::Connection::Base 3 identified_by :current_user 4 5 def connect 6 reject_unauthorized_connection unless find_verified_user 7 end 8 9 private 10 11 def find_verified_user 12 self.current_user = env['warden'].user 13 end 14 end 15end 16
Ruby
1 2class ChatRoomChannel < ApplicationCable::Channel 3 def subscribed 4 stream_from "chat_room_channel" 5 end 6 7 def unsubscribed 8 # Any cleanup needed when channel is unsubscribed 9 end 10 11 def speak(data) 12 ChatMessage.create!( 13 content: data['chat_message'], 14 user_id: current_user.id, 15 chat_room_id: data['chat_room_id'] 16 ) 17 end 18end 19
javascript
1 2import consumer from "./consumer" 3 4const appChatRoom = consumer.subscriptions.create("ChatRoomChannel", { 5 connected() { 6 // Called when the subscription is ready for use on the server 7 }, 8 9 disconnected() { 10 // Called when the subscription has been terminated by the server 11 }, 12 13 received(data) { 14 const chatMessages = document.getElementById('chat-messages'); 15 chatMessages.insertAdjacentHTML('beforeend', data['chat_message']); 16 }, 17 18 speak: function (chat_message, chat_room_id) { 19 return this.perform('speak', { chat_message: chat_message, chat_room_id: chat_room_id }); 20 } 21}); 22if (/chat_rooms/.test(location.pathname)) { 23 $(document).on("keydown", ".chat-room__message-form_textarea", function (e) { 24 if (e.key === "Enter") { 25 const chat_room_id = $('textarea').data('chat_room_id') 26 appChatRoom.speak(e.target.value, chat_room_id); 27 e.target.value = ''; 28 e.preventDefault(); 29 } 30 }) 31} 32
Ruby
1 2class ChatMessageBroadcastJob < ApplicationJob 3 queue_as :default 4 5 def perform(chat_message) 6 ActionCable.server.broadcast 'chat_room_channel', chat_message: render_chat_message(chat_message) 7 end 8 9 private 10 11 def render_chat_message(chat_message) 12 ApplicationController.renderer.render(partial: 'chat_messages/chat_message', locals: { chat_message: chat_message, current_user: chat_message.user }) 13 end 14end 15 16
試したこと
An unauthorized connection attempt was rejected
というエラーから、deviseのUser情報が正しくAction Cableに認証されていないと考えましたが、self.current_user = env['warden'].userで認証許可をしてます。
補足情報(FW/ツールのバージョンなど)
2日間かけ、自力で解決しようと試行錯誤しましたが無理でした。。
不足情報などありましたら修正しますので、ご教示いただければ幸いです。
よろしくお願いします。
あなたの回答
tips
プレビュー