Add paramRoot support for your Rails Backbone app
Out of the box, Backbone doesn't include a param root by default when sending requests off to your rails app.
There are gems like backbone-rails that offer some syntactic sugar with a paramRoot feature.
var User = Backbone.Model.extend({
paramRoot: 'user'
});
Which lets you do
User.new(params[:user])
in your controllers.
But here's a lighter way to add paramRoot sugar support:
Backbone.sync calls toJSON()
when it sends data off to your app. The method is pretty bare, but it gets passed an options object. So well just make it a little smarter and pass it a indicator if it wants to wrap everything in a param root:
_.extend(Backbone.Model.prototype, {
//override backbone json
toJSON: function(options) {
var data = {},
attrs = _.clone(this.attributes);
//if the model has a paramRoot attribute, use it as the root element
if(options && options.includeParamRoot && this.paramRoot) {
data[this.paramRoot] = attrs;
} else {
data = attrs;
}
return data;
}
});
Additionally, we'll override Backbone.sync
so it'll automatically pass an includeParamRoot indicator to toJSON()
on create, update, and patch:
//store the old sync, this is to make testing easier.
Backbone.oldSync = Backbone.sync;
//replace backbone sync with our own version.
Backbone.sync = function( method, model, options ) {
//pass in a includeParamRoot = true to the options
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
options.includeParamRoot = true;
}
return Backbone.oldSync.apply(this, [method, model, options]);
};
Here's the finished product:
//Smarter JSON, we overwrite sync to keep rails convention of having a root
//to requests.
!function(Backbone){
//store the old sync, this is to make testing easier.
Backbone.oldSync = Backbone.sync;
//replace backbone sync with our own version.
Backbone.sync = function( method, model, options ) {
//pass in a includeParamRoot = true to the options
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
options.includeParamRoot = true;
}
return Backbone.oldSync.apply(this, [method, model, options]);
};
_.extend(Backbone.Model.prototype, {
//override backbone json
toJSON: function(options) {
var data = {},
attrs = _.clone(this.attributes);
//if the model has a paramRoot attribute, use it as the root element
if(options && options.includeParamRoot && this.paramRoot) {
data[this.paramRoot] = attrs;
} else {
data = attrs;
}
return data;
}
});
}(Backbone);
Written by Johny Ho
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Ruby
Authors
Filed Under
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#