# console
brew install redis
brew services start redis
# development.rb
config.action_cable.mount_path = '/websocketier'
# application.html.erb
<%= action_cable_meta_tag %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
# cable.js
//= require action_cable
//= require_self
//= require_tree ./channels
(function() {
this.App || (this.App = {});
App.cable = ActionCable.createConsumer($('meta[name=action-cable-url]').attr('content'));
}).call(this);
# console
rails g channel chat
# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
def subscribed
stream_from "chat"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
end
# messages_controller.rb
def create
message = Message.create(params[:message].permit!)
# ActionCable.server.broadcast "chat", {
# message: MessagesController.render(
# partial: 'message',
# locals: { message: message }
# ).squish
# }
end
# message.rb
class Message < ApplicationRecord
# after_create_commit {
# ActionCable.server.broadcast "chat", {
# message: MessagesController.render(
# partial: 'message',
# locals: { message: message }
# ).squish
# }
# }
after_create_commit { MessageBroadcastJob.perform_later(self) }
end
# console
rails g job message_broadcast
# message_broadcast_job.rb
class MessageBroadcastJob < ApplicationJob
queue_as :default
def perform(message)
ActionCable.server.broadcast "chat", { message: render_message(message) }
end
private
def render_message(message)
MessagesController.render(partial: 'message', locals: {message: message}).squish
end
end
# app/assets/javascripts/channels/chat.js
App.chat = App.cable.subscriptions.create("ChatChannel", {
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
$('.messages').prepend(data['message']);
},
});