# 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']); }, });