ActionCableの使い方

参考サイト

Rails5.2が出たし、このタイミングでActionCableを使う - ひよっこエンジニアの雑多な日記

Action Cableでリアルタイムチャットアプリの作成方法 (Rails 5.1.4にて)(その1) herokuで動かす! - Qiita

久しぶりに授業とインターン以外で勉強できたので記録。

 

1.下準備

$ rails new actionCableTest

$ cd actionCableTest

$ rails db:create

 

2.コントローラー生成

$ rails g controller chat_rooms show

 

3.モデル生成

$ rails g model chat_message content:text

$ rails db:migrate

 

4.Controller編集

app/controllers/chat_rooms_controller.rb

class ChatRoomsController < ApplicationController
def show
@chat_messages = ChatMessage.all
end
end

 

5.View編集

app/views/chat_rooms/show.html.erb

<h2>ChatRoom</h2>
<div id="chat">
<% @chat_messages.each do |chat_message| %>
<p><%= chat_message.content %></p>
<% end %>
</div>

 

6.routeの訂正

config/routes.rb

Rails.application.routes.draw do
root 'chat_rooms#show'
end

 

7.channelの生成

$ rails g channel chat_room speak

 

動作確認

$ rails s

http://localhost:3000

DevelopperTool(F12) -> Console

App.chat_room.speak()

trueが帰ってくるはず!

 

8.channel編集

app/channels/chat_room_channel.rb

class ChatRoomChannel < ApplicationCable::Channel
def subscribed
stream_from 'chat_room_channel'
end

def unsubscribed
# Any cleanup needed when channel is unsubscribed
end

def speak(data)
chat_message = ChatMessage.create!(content: data['message'])
ActionCable.server.broadcast 'chat_room_channel', message: chat_message.content
end
end

 

app/assets/javascripts/channels/chat_room.js

App.chat_room = App.cable.subscriptions.create("ChatRoomChannel", {
connected: function() {
// Called when the subscription is ready for use on the server
},

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

received: function(data) {
// Called when there's incoming data on the websocket for this channel
var chat = document.getElementById('chat');
var newMessage = document.createElement('p');
newMessage.innerText = data['message'];
chat.appendChild(newMessage)
},

speak: function(message) {
return this.perform('speak', { message: message });
}
});

 

9.view編集

app/views/chat_rooms/show.html.erb

<h2>ChatRoom</h2>
<div id="chat">
<% @chat_messages.each do |chat_message| %>
<p><%= chat_message.content %></p>
<% end %>
</div>

<form>
投稿: <input type="text" />
<input type="submit" value="投稿" onClick="postChatMessage()" />
</form>

 

10.JSのメソッド追加

app/assets/javascripts/application.js

function postChatMessage() {
event.preventDefault();
var element = document.querySelector('input[type="text"]');
App.chat_room.speak(element.value);
element.value = '';
}