Skip to content

Instantly share code, notes, and snippets.

@trydionel
Created November 28, 2010 16:47
Show Gist options
  • Save trydionel/719080 to your computer and use it in GitHub Desktop.
Save trydionel/719080 to your computer and use it in GitHub Desktop.
Makes Backbone.js play nicely with default Rails setup
//
// Backbone.Rails.js
//
// Makes Backbone.js play nicely with the default Rails setup, i.e.,
// no need to set
// ActiveRecord::Base.include_root_in_json = false
// and build all of your models directly from `params` rather than
// `params[:model]`.
//
// Load this file after backbone.js and before your application JS.
//
Backbone.RailsJSON = {
// In order to properly wrap/unwrap Rails JSON data, we need to specify
// what key the object will be wrapped with.
_name : function() {
if (!this.name) throw new Error("A 'name' property must be specified");
return this.name;
},
// A test to indicate whether the given object is wrapped.
isWrapped : function(object) {
return (object.hasOwnProperty(this._name()) &&
(typeof(object[this._name()]) == "object"));
},
// Extracts the object's wrapped attributes.
unwrappedAttributes : function(object) {
return object[this._name()];
},
// Wraps the model's attributes under the supplied key.
wrappedAttributes : function() {
var object = new Object;
object[this._name()] = _.clone(this.attributes);
return object;
},
// Sets up the new model's internal state so that it matches the
// expected format. Should be called early in the model's constructor.
maybeUnwrap : function(args) {
if (this.isWrapped(args)) {
this.set(this.unwrappedAttributes(args), { silent: true });
this.unset(this._name(), { silent: true });
this._previousAttributes = _.clone(this.attributes);
}
}
};
_.extend(Backbone.Model.prototype, Backbone.RailsJSON, {
// This is called on all models coming in from a remote server.
// Unwraps the given response from the default Rails format.
parse : function(resp) {
return this.unwrappedAttributes(resp);
},
// This is called just before a model is persisted to a remote server.
// Wraps the model's attributes into a Rails-friendly format.
toJSON : function() {
return this.wrappedAttributes();
},
// A new default initializer which handles data directly from Rails as
// well as unnested data.
initialize : function(args) {
this.maybeUnwrap(args);
}
});
@dmix
Copy link

dmix commented Mar 24, 2011

this should be moved to a repo so it can be searched/contributed to.

@drewda
Copy link

drewda commented Mar 26, 2012

I just tried upgrading to Backbone 0.9.2 and now I'm getting this error: Uncaught TypeError: Cannot call method 'hasOwnProperty' of undefined. Anyone have a fix to suggest?

@thenickcox
Copy link

@drewda, your comment was 11 months ago, but I ran into this, too. My fix was to give it an || {} when it was asking for args in case args was undefined. Hope that helps anyone who gets here from Google.

@macool
Copy link

macool commented Jun 3, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment