If you want to serve your digital native customers with a web application you need to be mobile first , api-driven and the user experience should be rock solid. Your web application should reflect changes and interactions in (near) real-time without page loads or other lagging stuff causing to break the flow of the customer.
This blog post will explain the concept and how to use ActionCables with your Rails application and the Vue.js framework.
Reactive programming
The last decade most UI/UX are based on the paradigm of reactive programming. Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change.
In normal human words:
If the state of your application change it will be reflected in the customer's user interface. The change can be customer inflicted or by the backend services.
Javascript frameworks like React, Vue.js are supercharging your journey into reactive programming. But to provide real-time changes we need something lightweight and fast instead of polling a JSON based backend API causing load on your API and timing lag.
WebSockets , give you lightweight real-time connection to your backend.
Websockets
The WebSocket protocol enables interaction between a browser and a web server with lower overheads, facilitating real-time data transfer from and to the server. This is made possible by providing a standardized way for the server to send content to the browser without being solicited by the client, and allowing for messages to be passed back and forth while keeping the connection open.
In this way, a two-way (bi-directional) ongoing conversation can take place between a browser and the server. The communications are done over TCP port number 80 (or 443 in the case of TLS-encrypted connections), which is of benefit for those environments which block non-web Internet connections using a firewall.
But how do we use this with our Rails application and integrate this with Vue.js?
Meet ActionCables.
What are ActionCables?
Action Cable seamlessly integrates WebSockets with the rest of your Rails application. It allows for real-time features to be written in Ruby in the same style and form as the rest of your Rails application, while still being performant and scalable.
It's a full-stack offering that provides both a client-side JavaScript framework and a server-side Ruby framework. You have access to your full domain model written with Active Record or your ORM of choice.
Simple ActionCable with Vue.js example
The best way to show you how to supercharge your app is an example. You can find the project on Github to get all the code and run it yourself.
This is an example is a simple chat app which just broadcast all the message send to the connected clients. You can open as much browser windows you like, change the name and start chatting using ActionCables.
Flow
- Client post Message through Vue.js
- Vue.js will send the Message through ActionCable to the backend (Rails)
- Backend will broadcast Message to all connected clients
- Vue.js pickups the broadcasted Message and render the change.
Gossip example
Here's how the Gossip example looks like:
Adding Vue.js awesomeness to our Rails app
To make our life easier, we need to include JQuery and Vue.js on our Rails app. Adding this gems to your Gemfile
:
gem 'vuejs-rails'
gem 'jquery-rails'
Of course, we need to include Vue.js in our application.js
//= require jquery
//= require jquery_ujs
//= require rails-ujs
//= require vue
//= require_tree .
And make some changes to our application.html.erb
. Notice we moved the include tag for application
to the bottom, because we need the DOM to be fully in-mem before we get the Vue.js magic. Also, we need to include the action_cable meta tags!
<!DOCTYPE html>
<html>
<head>
<title>Gossip</title>
<%= csrf_meta_tags %>
<%= action_cable_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all' %>
</head>
<body>
<%= yield %>
</body>
<%= javascript_include_tag 'application' %>
</html>
Connecting to the backend
Of course, we need to connect through Websockets (ActionCable) to our backend. We subscribe to our GossipChannel ActionCable backend and we implemented a send_message
method which can be called from Vue.js to send a message. Note the received
function to get all the message you receive over the GossipChannel through ActionCable.
The second half of this code is a simple Vue.js model with two methods to add a message (receiveMessage
) to the data model and send a message (sendMessage
) to ActionCable.
Implementing the frontend
The frontend is a simple HTML form with Vue.js tags ({{ gossip.message }}
) to get the data rendered and provide two inputs to change the name of the Gossiper and the functionality to send a message on the keydown event (@keyup.enter="sendMessage"
).
Implementing the backend
The backend is an ActionCable channel for receiving the message and broadcast it straight away. We don't use a data storage for this, just a simple ping-pong.
With the statement ActionCable.server.broadcast CHANNEL_NAME, { message: data['message'], name: data['name']}
we broadcast back on the CHANNEL_NAME
the data we received from the connected clients.
Easy and powerful!
Deploy to Cloud 66
Cloud 66 for Rails builds, manages and maintains your ActionCable infused Rails applications that can be deployed to any cloud provider or to your own server. It helps you scale your database with master-slave replication, without having to make any configuration changes. You can add back-ups, load balancers and de-commission servers with a single click.
Watch this short introduction demo to some of the features and benefits of using Cloud 66 for Rails to deploy your Rails appls to any server or cloud.
Enjoy and explore the combination of Rails, Vue.js and ActionCables. A great combo!