Permalink
Browse files

Initial extracted implementation:

Ruby: BackboneSync::Rails::Faye::Observer
Javascript: BackboneSync.RailsFayeSubscriber
  • Loading branch information...
1 parent 483fc91 commit 3f4b205355f1ad4b8271d1cbb2545bd72f821097 @jasonm jasonm committed Aug 28, 2011
@@ -1,2 +1,6 @@
+require 'backbone_sync-rails/faye'
+
module BackboneSyncRails
+ class Engine < ::Rails::Engine
+ end
end
@@ -0,0 +1,9 @@
+require 'backbone_sync-rails/faye/observer'
+
+module BackboneSync
+ module Rails
+ module Faye
+ mattr_accessor :root_address
+ end
+ end
+end
@@ -0,0 +1,28 @@
+require 'backbone_sync-rails/faye/message'
+
+module BackboneSync
+ module Rails
+ module Faye
+ class Event
+ def initialize(model, event)
+ @model = model
+ @event = event
+ end
+
+ def broadcast
+ Message.new(channel, data).send
+ end
+
+ private
+
+ def channel
+ "/sync/#{@model.class.table_name}"
+ end
+
+ def data
+ { @event => { @model.id => @model.as_json } }
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,31 @@
+require 'net/http'
+require 'json'
+
+module BackboneSync
+ module Rails
+ module Faye
+ # To publish from outside of an `EM.run {}` loop:
+ # http://groups.google.com/group/faye-users/browse_thread/thread/ae6e2a1cc37b3b07
+ class Message
+ def initialize(channel, data)
+ @channel = channel
+ @data = data
+ end
+
+ def send
+ Net::HTTP.post_form(uri, :message => payload)
+ end
+
+ private
+
+ def uri
+ URI.parse("#{BackboneSync::Rails::Faye.root_address}/faye")
+ end
+
+ def payload
+ {:channel => @channel, :data => @data}.to_json
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,21 @@
+require 'backbone_sync-rails/faye/event'
+
+module BackboneSync
+ module Rails
+ module Faye
+ module Observer
+ def after_update(model)
+ Event.new(model, :update).broadcast
+ end
+
+ def after_create(model)
+ Event.new(model, :create).broadcast
+ end
+
+ def after_destroy(model)
+ Event.new(model, :destroy).broadcast
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,31 @@
+window.BackboneSync = {}
+
+class BackboneSync.RailsFayeSubscriber
+ constructor: (collection, options) ->
+ @collection = collection
+ @client = new Faye.Client('<%= BackboneSync::Rails::Faye.address %>/faye')
+ @channel = options.channel
+
+ @subscribe()
+
+ subscribe: =>
+ @client.subscribe "/sync/#{@channel}", @receive
+
+ receive: (message) =>
+ $.each message, (event, eventArguments) =>
+ @[event](eventArguments)
+
+ update: (params) =>
+ $.each params, (id, attributes) =>
+ model = @collection.get(id)
+ model.set(attributes)
+
+ create: (params) =>
+ $.each params, (id, attributes) =>
+ model = new @collection.model(attributes)
+ @collection.add(model)
+
+ destroy: (params) =>
+ $.each params, (id, attributes) =>
+ model = @collection.get(id)
+ @collection.remove(model)
@@ -0,0 +1,11 @@
+Backbone.Collection.prototype._addWithIdCheck = function(model, options) {
+ var idAttribute = model.idAttribute || this.model.prototype.idAttribute;
+ var modelId = model[idAttribute];
+
+ if (this.get(modelId) === undefined) {
+ this._addWithoutIdCheck(model, options);
+ }
+};
+
+Backbone.Collection.prototype._addWithoutIdCheck = Backbone.Collection.prototype._add;
+Backbone.Collection.prototype._add = Backbone.Collection.prototype._addWithIdCheck;

0 comments on commit 3f4b205

Please sign in to comment.