4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

リアルタイムなメッセージのやり取りをしたい、、が叶うAcitonCable実装しませんか?[初心者向けに丁寧に]

Posted at

どうもこんにちは,

今回は、リアルタイムのメッセージのやり取りを可能にする

Action Cable

について初心者の僕が初心者の目線に立ち、
かなり丁寧めに紹介してきたいと思います!

まずは、お使いのエディターを開き、

rails g channel message

このコマンドを打つと、 javascriptのファイルとRubyのファイル どっちもを作ってくれるのでオススメです⭐ (この星記号みずらっ、、)
そして、まずはコントローラーからいじっていきます。
message_controller.rb

class MessagesController < ApplicationController
  def index
    @item = Item.find(params[:item_id])アイテムからidを取り出す。
    @message = Message.new 新しいの生み出す
    @messages = Message.all 全部表示
  end

  def new 
    @item = Item.find(params[:item_id])
    @message = @item.messages.new 関連付け
    @messages = @item.messages 
  end
 
  def creat
    @item = Item.find(params[:item_id])
    @message = @item.messages.new(message_params)
    ActionCable.server.broadcast 'message_channel', content: @message if @message.save  *@messagecontextに代入
    redirect_to "/items/#{@item.id}/messages"メッセージ表示画面にリダイレクト
  end 

  private

  def message_params
    params.require(:message).permit(:message_text).merge(user_id: current_user.id)
  end
end

*マークが付いた contextキーはは後でjavascriptの記述を加える時に使うので忘れずに記入してください。

この後form_withを使うのですが、
form_withを使うと、情報がnewメソッドを通ってcreateメソッドを通ります。

今回はmessage画面の
index画面でやり取りをしたかったので
こうしました


message画面はこんな漢字:thunder_cloud_rain:

messages/index.html.erb
<div id='messages'>
<% @item.messages.order(created_at: :DESC).each do |message| %> DESCを使うことで、新しい順で並べてます
  <div class = "message-head">
   <div class = "message-text">
    <p><%= message.message_text %></p>
    </div>
   <div class="message-box">
      <%= message.user.nickname%> //メッセージに紐付いたユーザー名表示
    </div>
  <% end %>
  </div>

<%# 送信ゾーン %>

  <div class="box"> 
    <%= form_with(model: [@item, @message], local: true) do |f| %> 
     <%= f.text_field :message_text, id: "message_text" %>
     <%= f.submit '送信' %>
    <% end %>
    <br/>
     <%= link_to '戻る', "/", class: "finish-btn" %></li> 
 </div>
</div>

form_withのあとのmodel: [@item, @message]は
ネスト構造の時に使います。
つぎはjavascriptに記入していきます

message_channel.js
import consumer from "./consumer"

consumer.subscriptions.create("MessageChannel", {
  connected() {
    // Called when the subscription is ready for use on the server
  },

  disconnected() {
    // Called when the subscription has been terminated by the server
  },

  received(data) {   ここから追加
    const html = `<p>${data.content.message_text}</p>`;
    const messages = document.getElementById('messages');
    const newMessage = document.getElementById('message_text');
    console.log(html)
    messages.insertAdjacentHTML('afterbegin', html);
    newMessage.value='';
ここまで
    // Called when there's incoming data on the websocket for this channel
  }
});

ここで先程@messageの値を導入したcontextを使います

afterbeginは第ニ引数のhtmlより後に要素を入れるよ〜
という合図を表しています。

console.logはなくてもいいです。
(確認の為おいて、そのまま忘れてました。。)

packsのapplication.jsに記述がいらないのでお手軽ですよね


はいっ、できました!!


と思ったところで、、
ちょっと待ってください!:fireworks:

ごめんなさい。最後の仕上げがありました。。

最後はサーバー側とクライアント側をつなぐため、
Action Cable特有のメソッドを使っていきます!!


channel/message_channel.rb
class MessageChannel < ApplicationCable::Channel
  def subscribed
    # stream_from "some_channel"
    stream_from 'message_channel'  加えたところ
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
end

stream_formと
stream_forがあるらしいのですが

stream_formのほうが強力なんだなとだけ理解してます。:sunny:

詳しく知りたい方はこちら

ActionCableの stream_from stream_forの違いは何ですか?


メッセージ機能の実装は他にもあるらしので、

ActionCableなんてもんつかいたくねーし!

という方は,こちらを参考にお願いします!!
Rails: StimulusReflexとCableReadyでチャット機能を作ってみる

では今回はこれでおしまいにします!

ありがとうございました!

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?