質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Action Cable

Action Cableは、WebSocketをRailsに組み込む機能。Rails4でオプションとして存在していたWebSocketをRails5で標準機能したものです。Railsアプリケーションと同様のスタイルで、Rubyを用いたリアルタイム機能を記述できます。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

0回答

1167閲覧

Aciton CableとAjax通信を用いたチャット機能のメッセージの送信がうまく処理されない(難易度高め)

nomuno

総合スコア4

Action Cable

Action Cableは、WebSocketをRailsに組み込む機能。Rails4でオプションとして存在していたWebSocketをRails5で標準機能したものです。Railsアプリケーションと同様のスタイルで、Rubyを用いたリアルタイム機能を記述できます。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2020/09/03 02:33

編集2020/09/03 02:46

前提・実現したいこと

Action CableとAjax通信を用いてリアルタイムでチャットできるシステムを作っています。
ログインしているユーザーか否かでメッセージの表示位置を分けたところ、非同期通信によるメッセージのやり取りができなくなってしまいました。
(表示位置を分けるまでは非同期通信によるリアルタイムのチャットができていました。)

機能概要(テーブルの種類)

  • ユーザー管理機能の実装
  • ルーム管理機能
  • メッセージ投稿機能
  • ユーザーとルームの中間テーブル

機能の詳細

メッセージの送受信にはAction CableとAjaxを用いて実装しています。
送信の際はAciton Cableのspeakメソッドは使わずに、Ajaxを用いています。
ログインしたユーザーはルームの選択をすることが出来て、同じルームにいるユーザー全員とリアルタイムでチャットができます。
メッセージはログインしているユーザーか否かで、表示位置を分けています。
また、メッセージも各ルームにネストして、ルームごとに表示しています。
メッセージは無限スクロール機能を実装しており、新しい100件のみのメッセージの読み込みとなっています。

発生している問題・エラーメッセージ

メッセージの投稿をした際に、メッセージがリロードしないと読み込まれないという不具合が発生しています。
このエラーは、ユーザーによってメッセージの表示位置を変更する機能を実装するまではなかったエラーになります。
ターミナルにて確認すると以下のような結果が反映されることから、メッセージ表示の条件分岐またはそれに関するファイルにて問題が起きているものと思うのですが、その問題を見つけられません。

ActionView::Template::Error (Devise could not find the `Warden::Proxy` instance on your request environment. Make sure that your application is loading Devise and Warden as expected and that the `Warden::Manager` middleware is present in your middleware stack. If you are seeing this on one of your tests, ensure that your tests are either executing the Rails middleware stack or that your tests are using the `Devise::Test::ControllerHelpers` module to inject the `request.env['warden']` object for you.): 1: <div class="message" id="message-<%= message.id %>"> 2: <% if message.user_id == current_user.id %> 3: <div class="right_message"> 4: <p class="my_message_name"><%= message.user.nickname %></p> 5: <div class="my_message_content"> app/views/messages/_message.html.erb:2 app/models/message.rb:8:in `template' app/controllers/messages_controller.rb:6:in `create'

※ブラウザのコンソール上に下記の表示もされていましたので、こちらも追記しておきます。
on_content_end.js:54 on_content_end ==>response to loadPagePattern, href=http://localhost:3000/rooms/2, pattern.id=undefined

_message.html.erb

ruby

1<div class="message" id="message-<%= message.id %>"> 2 <% if message.user_id == current_user.id %> 3 <div class="right_message"> 4 <p class="my_message_name"><%= message.user.nickname %></p> 5 <div class="my_message_content"> 6 <%= simple_format(h message.content) %> 7 </div> 8 </div> 9 <% else message.user_id != current_user.id %> 10 <div class="left_message"> 11 <div class="your_message"> 12 <p class="your_message_name"><%= message.user.nickname %></p> 13 <div class="your_message_content"> 14 <%= simple_format(h message.content) %> 15 </div> 16 </div> 17 </div> 18 <% end %> 19</div>

message_controller.rb

ruby

1class MessagesController < ApplicationController 2 def create 3 @room = Room.find(params[:room_id]) 4 @message = current_user.messages.create!(message_params) 5 ActionCable.server.broadcast "room_channel", message: @message.template 6 end 7 8 private 9 def message_params 10 params.require(:message).permit(:content).merge(room_id: @room.id) 11 end 12end 13

message.rb

ruby

1class Message < ApplicationRecord 2 belongs_to :user 3 belongs_to :room 4 validates :user_id, presence: true 5 validates :content, presence: true, length: { maximum: 500 } 6 7 def template 8 ApplicationController.renderer.render partial: "messages/message", locals: { message: self } 9 end 10end 11

rooms_controller

ruby

1class RoomsController < ApplicationController 2 3 def index 4 @rooms = Room.all.order(:id) 5 end 6 7 def new 8 @room = Room.new 9 @room.users << current_user 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 def show 22 @room = Room.find(params[:id]) 23 @messages = @room.messages.includes(:user).order(:id).last(100) 24 @message = current_user.messages.build 25 end 26 27 def show_additionally 28 last_id = params[:oldest_message_id].to_i - 1 29 @messages = Message.includes(:user).order(:id).where(id: 1..last_id).last(50) 30 end 31 32 private 33 34 def room_params 35 params.require(:room).permit(:name).merge(user_ids: current_user.id) 36 end 37end

show.html.erb(rooms)

ruby

1<div id="message-container" data-room_id = "<%= @room.id %>"> 2 <%= render @messages %> 3</div> 4<%= render 'footer' %>

補足情報(FW/ツールのバージョンなど)

  • Ruby ver 2.6,5
  • Ruby on Rails ver 6.0.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問