ABOUT ARI

  • Ari 0 reviews

Overview

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.

 

Application

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.

#models/user.rb

..

has_many: chatrooms, dependent: :destroy

..

 

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

#controllers/chatroomcontroller.rb

 

class ChatRoomsController < ApplicationController

 def index

   @chat_rooms = ChatRoom.all

 end

 

 def new

   @chat_room = ChatRoom.new

 end

 

 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

   else

     render ‘new’

   end

 end

 

 private

 

 def chat_room_params

   params.require(:chat_room).permit(:title)

 end

end

 

 

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’ %>

</p>

 

<ul>

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

</ul>

 

 

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’ %>

 </div>

 

 <%= 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

url: YOUR_URL

 

 

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

 

   messages_to_bottom()

 

   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’]

       messages_to_bottom()

 

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

       textarea.val(”)

     e.preventDefault()

     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

views/chat_rooms/show.html.erb

<%= 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>

 </div>

 

 <%= 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

end

..

 

In the show view, show.html.erb

..

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

 <%= render @chat_room.messages %>

</div>

..

 

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”

 end

 

 def unsubscribed

   # Any cleanup needed when channel is unsubscribed

 end

 

 def send_message(data)

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

 end

end

 

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

   end

 

   protected

 

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

     if verified_user = env[‘warden’].user

       verified_user

     else

       reject_unauthorized_connection

     end

   end

 end

end

 

 

Conclusion

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.

INFO

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