LoginSignup
0
2

More than 3 years have passed since last update.

ActionCableでのメッセージ機能について

Last updated at Posted at 2021-04-17

ActionCableについて

ActionCableとは、通常のRailsアプリケーションと同様の記述で、即時更新機能を実装できるフレームワークです。例えば、メッセージやコメントを即時表示させたい場合に使用します

実装について

まずは以下のコマンドをターミナルで打ち込んでください

rails g channel message

このようになれば成功です。

Running via Spring preloader in process 11084
      invoke  test_unit
      create  test/channels/message_channel_test.rb
      create  app/channels/message_channel.rb
   identical  app/javascript/channels/index.js
   identical  app/javascript/channels/consumer.js
      create  app/javascript/channels/message_channel.js

今回の実装では以下の2つのファイルについて理解する必要があります。

message_channel.rb
クライアントとサーバーを結びつけるためのファイルです。

message_channel.jsの役割
サーバーから送られてきたデータをクライアントの画面に描画するためのファイルです


では、さっそくコードを書いていきます。
まずは、サーバーとクライアントを結び付けます。

app/channels/message_channel.rb
class MessageChannel < ApplicationCable::Channel
  def subscribed
    stream_from "message_channel"
  end

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

このとき出てくるstream_fromは、ActionCableで用意されているメソッドでサーバとクライアントを関連づけます。この関連づけられたことで作られるデータの経路をboradcast(ブロードキャスト)と言います。

次にコントローラの編集をしましょう

app/controller/messages_controller.rb
class MessagesController < ApplicationController
  def new
    @messages = Message.all
    @message = Message.new
  end

  def create
    @message = Message.new(text: params[:message][:text])
    if @message.save
      ActionCable.server.broadcast 'message_channel', content: @message
    end
  end
end

下から四行目に着目してください。
broadcastを通して、'message_channel'に向けて@messageを送信するという意味です。content:@messageの指定ミスに注意してください。

さて、いよいよjsファイルを編集します。

app/javascript/channels/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.text}</p>`;
    const messages = document.getElementById('messages');
    const newMessage = document.getElementById('message_text');
    messages.insertAdjacentHTML('afterbegin', html);
    newMessage.value='';
  }
});

ここで出てくるdataは送られてくる情報を受け取っています。
data.contentで,createアクションで指定したインスタンス(@message)を取り出しています。

あとは、通常のJavascriptと同様です。なお、newMessage.value="";としているのはメッセージ入力・送信後は入力フォームに文字を残しておきたく泣いためです。

あとはビューファイルを作って終わりです。お疲れ様でした!

new.html.erb
<%= form_with model: @message do |f| %>
  <%= f.text_field :text %>
  <%= f.submit '送信' %>
<% end %>
<div id='messages'>
  <% @messages.reverse_each do |message| %>
    <p><%= message.text %></p>
  <% end %>
</div>

終わりに

ActionCableの他にAjaxなどの似たような技術もあるので、そこについてはまた今度執筆します!!!

0
2
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
0
2