前提・実現したいこと
【環境】
- ruby-2.6.6
- Ruby on Rails 6.0.3.4
【達成したいこと】
チャット機能で 「content」 と 「image」 をリアルタイム送信をできるようにしたいです。
【現状】
「content」 送信はできております。そのため、画像送信も実装しようと思い模索中です。
Action Cable についての記事を参考にさせていただいているのですが、実装できず質問させていただきました。
モデル同士の関係は
User
1has_many :chats, dependent: :destroy
Team
1has_many :chats, dependent: :destroy
Chat
1belongs_to :user 2belongs_to :team 3has_one_attached :photo
です。User
と Team
は中間テーブルでつながっております。
発生している問題・エラーメッセージ
画像送信を実装しようとしたら画像の blob: url
が content
カラムに入っていしまいます。また変更の影響でコンテントを普通に遅れない状況になっております。
該当のソースコード
- JS
chatchannel
1# app/javascript/channels/chat_channel.js 2 3import $ from 'jquery' 4import consumer from "./consumer" 5 6const autoScroll = () => { 7 let element = document.documentElement; 8 let bottom = element.scrollHeight - element.clientHeight; 9 window.scroll(0, bottom); 10} 11 12$(function() { 13 const chatChannel = consumer.subscriptions.create({ channel: 'ChatChannel', team: $('#chats').data('team_id') }, { 14 connected() { 15 autoScroll(); 16 }, 17 18 disconnected() { 19 }, 20 21 received(data) { 22 debugger 23 $('#chats').append(data['chat']); 24 autoScroll(); 25 }, 26 27 speak(chat, photo) { 28 debugger 29 return this.perform('speak', { 30 chat: chat, 31 photo: photo 32 }); 33 } 34 35 }); 36 37 $(".form-submit").on('click', function(e){ 38 debugger 39 if ($(".mychat_image > img") !== ('')) { 40 let img = $(".mychat_image > img"); 41 let photo = img[0]; 42 chatChannel.speak(photo); 43 } else if ($('.form-chat').val()) { 44 let chat = $('.form-chat').val(); 45 chatChannel.speak(chat); 46 } else if ($(".mychat_image > img") === ('') && $('.form-chat').val()) { 47 let chat = $('.form-chat').val(); 48 let img = $(".mychat_image > img"); 49 let photo = img[0]; 50 chatChannel.speak(chat, photo); 51 } 52 53 $(".form-chat").val('') 54 e.preventDefault(); 55 }); 56});
- プレビュー機能
preview
1# app/javascript/modules/preview.js 2 3 $('#chat_photo').on('change', (e) => { 4 $('.mychat_image > img').remove(); 5 const file = e.target.files[0]; 6 const blob = window.URL.createObjectURL(file); 7 8 const blobImage = $('.mychat_image').append('<img>'); 9 $('.mychat_image > img').attr('src', blob); 10 })
- ActionCable
chatchannelrb
1# app/channels/chat_channel.rb 2 3class ChatChannel < ApplicationCable::Channel 4 def subscribed 5 stream_from "chat_channel_#{params['team']}" 6 end 7 8 def unsubscribed 9 end 10 11 def speak(data) 12 Chat.create!( 13 content: data['chat'], 14 photo: data['photo'], 15 user_id: current_user.id, 16 team_id: params['team'] 17 ) 18 end 19end 20
- ブロードキャスト
broadcast
1# app/jobs/chat_broadcast_job.rb 2class ChatBroadcastJob < ApplicationJob 3 queue_as :default 4 5 def perform(chat, photo) 6 ActionCable.server.broadcast "chat_channel_#{chat.team_id}", chat: render_chat(chat) 7 end 8 9 private 10 11 def render_chat(chat, photo) 12 # ApplicationController.renderer.render partial: 'chats/chat', locals: { chat: chat } 13 renderer = ApplicationController.renderer.new( 14 http_host: 'localhost:80' 15 ) 16 renderer.render(partial: 'chats/chat', locals: { chat: chat }) 17 end 18end 19
- 送信部分
index
1# app/views/chats/index.html.haml 2 3 .chats#chats{"data-team_id": "#{@team.id}"} 4 = render @chats 5 .mychat_image 6 7 .form 8 .form-input 9 %label.form-image 10 = image_tag 'photo.png' 11 %input{type: "file", class: 'hidden', name: 'photo', id: 'chat_photo'}/ 12 = text_field_tag :content, nil, class: 'form-chat',placeholder: 'Aa' 13 %input{type: 'submit', class: 'form-submit'}
- 部分テンプレート
chat
1# app/views/chats/_chat.html.haml 2 3 .chat_content 4 %p= chat.content 5 = image_tag chat.photo, class: 'chat_image' if chat.photo.attached?
試したこと
以下参考にさせていただいた記事です。
画像送信の方は
補足情報(FW/ツールのバージョンなど)
この場での質問ははじめてです。情報など足りていない場合はご指摘いただけたら幸いです。
何卒よろしくお願いいたします。
あなたの回答
tips
プレビュー