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

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

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

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

Ruby

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

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Ruby on Rails

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

0回答

999閲覧

【Rails】Action Cableで画像送信をできるようにしたいです

susuke

総合スコア0

Action Cable

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

Ruby

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

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Ruby on Rails

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/01/17 08:58

前提・実現したいこと

【環境】

  • 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

です。UserTeam は中間テーブルでつながっております。

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

画像送信を実装しようとしたら画像の blob: urlcontent カラムに入っていしまいます。また変更の影響でコンテントを普通に遅れない状況になっております。

該当のソースコード

  • 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/ツールのバージョンなど)

この場での質問ははじめてです。情報など足りていない場合はご指摘いただけたら幸いです。
何卒よろしくお願いいたします。

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問