Giter Club home page Giter Club logo

sync's Introduction

Sync

This started as a thought experiment that is growing into a viable option for realtime Rails apps without ditching the standard rails stack that we love and are so productive with for a heavy client side MVC framework.

Real-time partials with Rails. Sync lets you render partials for models that, with minimal code, update in realtime in the browser when changes occur on the server.

Watch a screencast to see it in action

See it in action

In practice, one simply only needs to replace:

<%= render partial: 'user_row', locals: {user: @user} %>

with:

<%= sync partial: 'user_row', resource: @user %>

Then update views realtime with a simple sync_update(@user) in the controller without any extra javascript or configuration.

In addition to real-time updates, Sync also provides:

  • Realtime removal of partials from the DOM when the sync'd model is destroyed in the controller via sync_destroy(@user)
  • Realtime appending of newly created model's on scoped channels
  • JavaScript/CoffeeScript hooks to override and extend element updates/appends/removes for partials
  • Support for Faye and Pusher

Requirements

  • Ruby >= 1.9.2
  • Rails >= 3.1
  • jQuery

Installation

1) Add the gem to your Gemfile

Using Faye

gem 'faye'
gem 'thin'
gem 'sync'

Using Pusher

gem 'pusher'
gem 'sync'

Install

$ bundle
$ rails g sync:install

2) Require sync in your asset javascript manifest app/assets/javascripts/application.js:

//= require sync

3) Add the pubsub adapter's javascript to your application layout app/views/layouts/application.html.erb

<%= javascript_include_tag Sync.adapter_javascript_url %>

4) Configure your pubsub server (Faye or Pusher)

Using Faye (self hosted)

Set your configuration in the generated config/sync.yml file, using the Faye adapter. Then run Faye alongside your app.

rackup sync.ru -E production

Using Pusher (SaaS)

Set your configuration in the generated config/sync.yml file, using the Pusher adapter. No extra process/setup.

Determine if your configuration can run in async mode or not (true by default in sync.yml)

By Default, Sync runs in async mode, meaning all http post requests to the pubsub server will run in an eventmachine-http request, bypassing the need for a background job/worker and allowing the controller request-response times to remain unaffected by sync publishes. Running in async mode requires either an evented webserver like thin or manually running an eventmachine process in a seperate thread. For example, async mode works perfectly with unicorn using a configuration such as:

# config/unicorn.rb
worker_processes 3
preload_app true
timeout 30

before_fork do |server, worker|
  ActiveRecord::Base.connection.disconnect! if defined?(ActiveRecord::Base)
  EM.stop if defined?(EM) && EM.reactor_running?
end

after_fork do |server, worker|
  ActiveRecord::Base.establish_connection if defined?(ActiveRecord::Base)
  Thread.new { EM.run }
end

Current Caveats

The current implementation uses a DOM range query (jQuery's nextUntil) to match your partial's "element" in the DOM. The way this selector works requires your sync'd partial to be wrapped in a root level html tag for that partial file. For example, this parent view/sync partial approach would not work:

Given the sync partial _todo_row.html.erb:

Title:
<%= link_to todo.title, todo %>

And the parent view:

<table>
  <tr>
    <%= sync partial: 'todo_row', resource: @todo %>
  </tr>
</table>
The markup would need to change to:

sync partial _todo_row.html.erb:

<tr> <!-- root level container for the partial required here -->
  Title:
  <%= link_to todo.title, todo %>
</tr>

And the parent view changed to:

<table>
  <%= sync partial: 'todo_row', resource: @todo %>
</table>

I'm currently investigating true DOM ranges via the Range object.

View sync/users/_user_list_row.html.erb

<tr>
  <td><%= link_to user.name, user %></td>
  <td><%= link_to 'Edit', edit_user_path(user) %></td>
  <td><%= link_to 'Destroy', user, method: :delete, remote: true, data: { confirm: 'Are you sure?' } %></td>
</tr>

View users/index.html.erb

<h1>Some Users</h1>
<table>
  <tbody>
    <%= sync partial: 'user_list_row', collection: @users %>
  </tbody>
</table>

Controller

def UsersController < ApplicationController
  
  def update
    @user = User.find(params[:id])
    if user.save
    
    end

    # Sync updates to any partials listening for this user
    sync_update @user

    redirect_to users_path, notice: "Saved!"
  end

  def destroy
    @user = User.find(params[:id])
    @user.destroy

    # Sync destroy, telling client to remove all dom elements containing this user
    sync_destroy @user

    respond_to do |format|
      format.html { redirect_to users_url }
      format.json { head :no_content }
    end
  end
end

sync's People

Contributors

chrismccord avatar derekparker avatar nicholasklick avatar oneiros avatar stevestmartin avatar waymondo avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.