Let’s check how we can implement RethinkDB with ActionCable into Ruby on Rails application.
You can find all code in rethinkdb_example .
First of all, let’s create sample app with rails command:
rails new rethinkdb_example
And setup ActionCable route in routes.rb :
Rails . application . routes . draw do
mount ActionCable . server => '/cable'
end
We need to generate channel for active users:
rails g channel active_users
Let’s generate controller and set it to the root in routes.rb
rails g controller tasks index
Now, moving to RethinkDB .
RethinkDB is a document oriented data store much like MongoDB, but with some key advantages.
RethinkDB makes building and scaling realtime apps dramatically easier. Get started by installing the server, and jump into our getting started guide to start building your first app in minutes.
You can read more here .
Let’s integrate RethinkDB into our rails application.
We need two gems.
gem 'nobrainer'
gem 'nobrainer_streams'
Run bundle and installer script, to have your application use NoBrainer instead of ActiveRecord.
bundle && rails g nobrainer :install
Now, if you generate model User with rails g model User it will look like:
class User
include NoBrainer :: Document
include NoBrainer :: Document :: Timestamps
end
Now, let’s move to our ActiveUsersChannel . Here we have subscribed and unsubscribed methods.
They’re just calling then somebody open or close connection.
class ActiveUsersChannel < ApplicationCable :: Channel
include NoBrainer :: Streams
def subscribed
@user = User . create
stream_from User . all , include_initial: true
end
def unsubscribed
@user . destroy
end
end
Now, let’s change our tasks/index.html.erb we add here special div with active_users_list ID.
< section id = "active_users" >
< h2 > Active users < /h2>
<ul id="active_users_list">
</u l >
< /section>
Now let’s take a look into generated active_users.coffee file:
App . active_users = App . cable . subscriptions . create "ActiveUsersChannel" ,
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 ) ->
# Called when there's incoming data on the websocket for this channel
A little change here, for now just keep received event:
App . active_users = App . cable . subscriptions . create "ActiveUsersChannel" ,
received: ( data ) ->
if data . old_val && ! data . new_val
App . spreadsheet . remove_user ( data . old_val )
else if data . new_val
App . spreadsheet . new_user ( data . new_val )
Just update our ul by ID and add new data:
App . spreadsheet =
active_users : {}
new_user : ( user ) ->
@ active_users [ user . id ] = user
@ render_active_users ()
remove_user : ( user ) ->
delete @ active_users [ user . id ]
@ render_active_users ()
render_active_users : () ->
$ ( '#active_users_list' ). html (
( "<li> #{ user . id } </li>" for id , user of @ active_users ). join ( "" )
)
Now you can open browser window, then open second one, so you can see how new user will be added to the list. Or deleted - if you close browser.
Please enable JavaScript to view the comments powered by Disqus.