• Ari 0 reviews


On this Ruby on Rails tutorial, we will cover about Actioncable. A websocket protocol is a variation of HTTP that creates a continuous connection between client and server so that there exists two way connection between them. Using this we can achieve real time applications like chat apps, gaming apps that are powerful than ordinary web pages. HTTP is a half duplex connection meaning that at a given time there exists only one way connection. The example is a walkie talkie. In HTTP there exists request and response cycle, the server responds only if the client requests a resource. Web socket protocol is a full duplex connection between client and server, this allows them to connect persistently. Example is mobile phone.In rails world there used to be pooling instead of websockets. Pooling means refreshing your browser in specific interval to check if something has changed in the server.

Now we have actioncable integrated into rails to make working with web sockets easier. We can get full persistent connection between client and server.



Let’s create a rails project without test suite to make it simple and integrate all the gems necessary, i.e devise and bootstrap.

$ rails new my_chat_app -T


In your Gemfile add the following gems


gem ‘devise’

gem ‘bootstrap-saas’, ‘~>3.3.6’



Run the bundler to install the gems. Rename the app/stylesheetw/application.css to app/stylesheets/application.scss and add the following import for bootstrap to work.

@import “bootstrap”


Now we need to work on devise for User model and configurations. Run these devise commands

$ rails g devise:install

$ rails g devise User username:string

$ rails g devise:views

$ rails db:migrate


Let’s add the filter to controller so that only logged in user can use our application. So in our application_controller.rb file add the following line


before_action :authenticate_user!



Next, we need to create models for chat room . A chat room must have a name and a creator. So run this command below

$ rails g model ChatRoom title:string user:references

$ rails db:migrate


A user can create many chat rooms. So let’s create the association.



has_many: chatrooms, dependent: :destroy



Next, we need a controller to our chat room. Let’s create a ChatRoomController.



class ChatRoomsController < ApplicationController

 def index

   @chat_rooms = ChatRoom.all



 def new

   @chat_room = ChatRoom.new



 def create

   @chat_room = current_user.chat_rooms.build(chat_room_params)

   if @chat_room.save

     flash[:success] = ‘Chat room added!’

     redirect_to chat_rooms_path


     render ‘new’






 def chat_room_params






Now let’s create a view that displays all of the chatrooms in views/chatrooms/index.html.erb

<h2>Chat rooms</h2>


<p class=”chatroom”>

       <%= link_to ‘New chat room’, new_chat_room_path, class: ‘btn btn-primary’ %>




 <%= render @chat_rooms %> # To display all the rooms




We need another view for creating a new chat room that contains the form for entering the details of chat room.

<h2>Create a chat room</h1>


<%= form_for @chat_room do |f| %>

 <div class=”form-group”>

   <%= f.label :title %>

   <%= f.text_field :title, autofocus: true, class: ‘form-control’ %>



 <%= f.submit “Add!”, class: ‘btn btn-primary’ %>

<% end %>



Now we have chatroom model and controller along with views. Now we need a message model . So let’s generate a model. We want to generate a scaffold for this.

$ rails g scaffold Message body:text user:references chat_room:references


Then run the migration.

Make sure you have the proper model associations for your message, user and chatroom models. And also use dependent: :destroy property for required models.

Adding ActionCable

For action cable to work, you need to install Redis into your machine. Then install the redis gem in your Gemfile. There already contains the gem you just need to uncomment it form the file.


gem ‘redis’,’~>3.2’



Run the bundler then. Next, we need to use the redis adapter for this to work so let’s change the config/cable.yml file.

adapter: redis




Now you need to change the routes to mount action cable. In your routes.rb file


mount ActionCable.server => ‘/cable’



In the javascript directory there must be a file called cable.js. You need to import that file into application.js manifest file


//= require cable



Next, we need to create a new channel. Call it javascript/channels/rooms.coffee

jQuery(document).on ‘turbolinks:load’, ->

 messages = $(‘#messages’)

 if $(‘#messages’).length > 0

   messages_to_bottom = -> messages.scrollTop(messages.prop(“scrollHeight”))




   App.global_chat = App.cable.subscriptions.create {

       channel: “ChatRoomsChannel”

       chat_room_id: messages.data(‘chat-room-id’)


     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) ->

       messages.append data[‘message’]



     send_message: (message, chat_room_id) ->

       @perform ‘send_message’, message: message, chat_room_id: chat_room_id



   $(‘#new_message’).submit (e) ->

     $this = $(this)

     textarea = $this.find(‘#message_body’)

     if $.trim(textarea.val()).length > 1

       App.global_chat.send_message textarea.val(), messages.data(‘chat-room-id’)



     return false


Here, the consumer is the one who gets subscribed to the channel and pass the room id. The subscription has number of callbacks that are connected, disconnected and received. We need to allow users to send their message and get messages. Let’s generate a view for that


<%= form_for @message, url: ‘#’ do |f| %>

 <div class=”form-group”>

   <%= f.label :body %>

   <%= f.text_area :body, class: ‘form-control’ %>

   <small class=”text-muted”>From 2 to 100 characters</small>



 <%= f.submit “Post”, class: ‘btn btn-danger btn-lg’ %>

<% end %>



Now in chatrooms controller


def show

 @chat_room = ChatRoom.includes(:messages).find_by(id: params[:id])

 @message = Message.new




In the show view, show.html.erb


<div id=”messages” data-chat-room-id=”<%= @chat_room.id %>”>

 <%= render @chat_room.messages %>




We need to introduce our channel to our server. So in channels/chat_rooms_channel.rb add the following code

class ChatRoomsChannel < ApplicationCable::Channel

 def subscribed

   stream_from “chat_rooms_#{params[‘chat_room_id’]}_channel”



 def unsubscribed

   # Any cleanup needed when channel is unsubscribed



 def send_message(data)

   current_user.messages.create!(body: data[‘message’], chat_room_id: data[‘chat_room_id’])




Next we need to change our channels/application_cable/connection.rb

module ApplicationCable

 class Connection < ActionCable::Connection::Base

   identified_by :current_user


   def connect

     self.current_user = find_verified_user

     logger.add_tags ‘ActionCable’, current_user.email





   def find_verified_user # this checks whether a user is authenticated with devise

     if verified_user = env[‘warden’].user











So by this point we have configured all the files for our chat app. We need to configure both client side and server side for those real time web applications. Action cable should only be used if real time feature is needed. It takes lot of bandwidth. So we need to make sure if we really need it. You can extend this app to whatever you like. You can add validations and so on. If you want to learn more about action cable and how it works you can visit http://edgeguides.rubyonrails.org/action_cable_overview.html

Project History & Review (0)

There are no projects found.


  • Member Sinced: December 26, 2013
  • Address:
  • Total spent: $0.00
  • Project posted: 0
  • Complete project(s): 0