Collaborate is a Rails Engine that allows Real-Time collaboration between users.
Collaborate is still a work in progress, and currently only text attributes may be collaboratively edited.
Add this line to your application's Gemfile:
gem 'collaborate'
And then execute:
$ bundle
You will need to have ActionCable set up. In particular, you will need an
ApplicationCable::Channel
and ApplicationCable::Connection
.
More information about setting up ActionCable can be found in its README.
class Document < ActiveRecord::Base
# Include the Collaborate::Document concern
include Collaborate::Document
# Choose which attributes may be edited collaboratively
collaborative_attributes :body, :title
end
Adding collaborative_attributes
will define an extra attribute on the model
prefixed with collaborative_
(e.g collaborative_body
). We must use that
over body
whenever we wish to allow realtime collaboration.
Bear in mind that the collaborative_
attributes are stored only in the Rails
cache. You must save these attributes where appropriate:
document = Document.first
document.body = document.collaborative_body
document.save!
# Or, using the commit_collaborative_attributes convenience method:
document.commit_collaborative_attributes(:body)
document.commit_collaborative_attributes(:body, :title)
You will need to set up a collaboration channel for each model that is being collaboratively edited.
class DocumentChannel < Collaborate::CollaborationChannel
private
# Set the Model class that we are editing.
def document_type
Document
end
end
As mentioned in Model Setup, we must use collaborative_
attributes over normal
attributes when getting the values of collaborative attributes:
<%# app/views/documents/show.html.erb %>
<input id="title" type="text" value="<%= @document.collaborative_title %>">
<textarea id="body" rows="8" cols="40"><%= @document.collaborative_body %></textarea>
<%= link_to 'Back', documents_path %>
<script>
var documentId = <%= @document.id %>
</script>
Add collaborate
to your application.coffee
asset, after actionable:
#= require cable
#= require collaborate
Then, wherever appropriate:
# Create a new ActionCable consumer
cable = Cable.createConsumer 'ws://localhost:28080'
# Set up our collaboration object. `documentId` is (as you may expect) the ID
# of the document that is being edited.
collaborate = new Collaborate(cable, 'DocumentChannel', documentId)
# We now specify the two attributes we are editing.
collaborativeTitle = collaborate.addAttribute('title')
collaborativeBody = collaborate.addAttribute('body')
# Here we are using a TextAreaAdapter - this binds to a textarea element.
# The TextAreaAdapter is the only adapter that is bundled with Collaborate.
# There is currently an AceAdapter in progress, and other adapters are
# relatively easy to write.
new Collaborate.Adapters.TextAreaAdapter(collaborativeTitle, '#title')
new Collaborate.Adapters.TextAreaAdapter(collaborativeBody, '#body')
Collaborate uses ActionCable to allow realtime communication between clients and the server.
All changes to an attribute are represented by an Operation. Operations are sent from the client to the server, which will then transform them as appropriate to ensure that they are applied in the same order.