Action Cable
メッセージの即時更新機能を実装するためには、Action Cableというフレームワークを使用します。このフレームワークは通常のRailsのアプリケーションと同様の記述で、即時更新を実装できます。
Channel(チャネル)
コメントなどを即時に表示させるために、データの経路を設定したり、送られてきたデータを表示させるJavaScriptを記述するのですが、これらの役割を担っているのがChannel(チャネル)です。即時更新機能を実現するサーバー側の仕組みのことをいいます。
実装方法
①チャネルの作成
% rails g channel comment
このコマンドをターミナルで実行すると以下のファイルが作成されます。
Running via Spring preloader in process 11084
invoke test_unit
create test/channels/comment_channel_test.rb
create app/channels/comment_channel.rb
identical app/javascript/channels/index.js
identical app/javascript/channels/consumer.js
create app/javascript/channels/comment_channel.js
②comment_channel.rbの編集
このファイルは、サーバーとクライアントを繋ぐファイルで、stream_fromメソッドを用いて、サーバーとクライアントの関連付けを設定します。
class MessageChannel < ApplicationCable::Channel
def subscribed
stream_from "comment_channel"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
end
③comments_contorller.rbの編集
コメントの保存が成功した時に、broadcastを介してコメントを送信されるように記述する。
※broadcastとは、サーバーから送られるデータの経路のこと。
class CommentsController < ApplicationController
def new
@comments = Comment.all
@comment = Comment.new
end
def create
@comment = Comment.new(text: params[:comment][:text])
if @comment.save
ActionCable.server.broadcast '@comment_channel', content: @comment
end
end
end
④comment_channel.jsの編集
import consumer from "./consumer"
consumer.subscriptions.create("CommentChannel", {
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 comments = document.getElementById('comments');
const newComment = document.getElementById('comment_text');
comments.insertAdjacentHTML('afterbegin', html);
newComment.value='';
}
});