[47]メッセージと会話 | 会話 << [ホームに戻る] >> [49]メッセージと会話| コメント
メッセージをリアルタイムで送りあうことができるようにします。
コマンド
rails g channel Message
ルートの設定をします。
記述追加 config\routes.rb
36行目に「mount ActionCable.server => '/cable'」の記述を追加しています。
Rails.application.routes.draw do # ルートを app\views\pages\home.html.erb に設定 root 'pages#home' devise_for :users, path: '', path_names: {sign_up: 'register', sign_in: 'login', edit: 'profile', sign_out: 'logout'}, controllers: {omniauth_callbacks: 'omniauth_callbacks', registrations: 'registrations'} get 'pages/home' get '/dashboard', to: 'users#dashboard' get '/users/:id', to: 'users#show', as: 'users' get '/selling_orders', to: 'orders#selling_orders' get '/buying_orders', to: 'orders#buying_orders' get '/all_requests', to: 'requests#list' get '/request_offers/:id', to: 'requests#offers', as: 'request_offers' get '/my_offers', to: 'requests#my_offers' get '/search', to: 'pages#search' get 'settings/payment', to: 'users#payment', as: 'settings_payment' get 'settings/payout', to: 'users#payout', as: 'settings_payout' get '/gigs/:id/checkout/:pricing_type', to: 'gigs#checkout', as: 'checkout' get '/conversations', to: 'conversations#list', as: "conversations" get '/conversations/:id', to: 'conversations#show', as: "conversation_detail" post '/users/edit', to: 'users#update' post '/offers', to: 'offers#create' post '/reviews', to: 'reviews#create' post '/settings/payment', to: 'users#update_payment', as: "update_payment" post 'messages', to: 'messages#create' put '/orders/:id/complete', to: 'orders#complete', as: 'complete_order' put '/offers/:id/accept', to: 'offers#accept', as: 'accept_offer' put '/offers/:id/reject', to: 'offers#reject', as: 'reject_offer' mount ActionCable.server => '/cable' resources :gigs do member do delete :delete_photo post :upload_photo end resources :orders, only: [:create] end resources :requests # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end
「app\channels\message_channel.rb」ファイルの記述を以下のように変更します。
記述変更 app\channels\message_channel.rb
class MessageChannel < ApplicationCable::Channel def subscribed conversation = Conversation.find params[:conversation] stream_for conversation end end
「app\controllers\messages_controller.rb」ファイルに記述を追加します。
記述追加 app\controllers\messages_controller.rb
20~36行目、41~43行目に記述を追加しています。
コードをコピーしてファイルの内容を置き換えて下さい。
class MessagesController < ApplicationController def create if current_user.id == message_params[:receiver_id] redirect_to request.referrer, alert: "自分にメッセージを送ることはできません" end conversation = Conversation.where("(sender_id = ? AND receiver_id = ?) OR (sender_id = ? AND receiver_id = ?)", current_user.id, message_params[:receiver_id], message_params[:receiver_id], current_user.id ).first if !conversation.present? conversation = Conversation.create(sender_id: current_user.id, receiver_id: message_params[:receiver_id]) end @message = Message.new(user_id: current_user.id, conversation_id: conversation.id, content: message_params[:content] ) if @message.save conversation.update!(updated_at: @message.created_at) receiver = conversation.sender.id == current_user.id ? conversation.receiver : conversation.sender MessageChannel.broadcast_to conversation, sender_id: current_user.id, sender: render_message(@message, current_user), receiver: render_message(@message, receiver) if URI(request.referrer).path == conversation_detail_path(id: receiver.id) return render json: {success: true} end redirect_to request.referrer, notice: "メッセージを送りました" else redirect_to request.referrer, alert: "メッセージを送れませんでした" end end private def render_message(message, user) self.render_to_string partial: 'conversations/message', locals: {m: message, user: user} end def message_params params.require(:message).permit(:content, :receiver_id) end end
「app\javascript\channels\message_channel.js」ファイルを以下のように編集します。
記述編集 app\javascript\channels\message_channel.js
import consumer from "./consumer" $(document).on('turbolinks:load', () => { $('[data-channel-subscribe="conversation"]').each(function(index, element) { var $element = $(element), $chatList = $('#message_list'), $form = $('#new_message'), conversation_id = $element.data('conversation-id'), user_id = $element.data('user-id') consumer.subscriptions.create( { channel: "MessageChannel", conversation: conversation_id }, { received: function(data) { if (data.sender_id == user_id) { $chatList.append(data.sender) } else { $chatList.append(data.receiver) } $form[0].reset(); $chatList.animate({ scrollTop: $chatList.prop("scrollHeight") }, 1000) } } ) }); });
ブラウザ確認
http://localhost:3000/conversations
メッセージを送るとリアルタイムで表示できるようになりました。
↓↓クリックして頂けると励みになります。