Adicione suporte paramRoot para seu aplicativo Rails Backbone

Fora da caixa, o Backbone não inclui uma raiz param por padrão ao enviar solicitações para seu aplicativo Rails.

Existem joias como backbone-rails que oferecem algum açúcar sintático com um recurso paramRoot.

var User = Backbone.Model.extend({
paramRoot
: 'user'
});

O que permite que você faça

User.new(params[:user])

em seus controladores.

Mas aqui está uma maneira mais leve de adicionar suporte para açúcar paramRoot:

Backbone.sync chama toJSON()quando envia dados para seu aplicativo. O método é bastante simples, mas é passado um objeto de opções. Então, vamos torná-lo um pouco mais inteligente e passar um indicador se ele quiser envolver tudo em uma raiz param:

_.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;
}
});

Além disso, iremos substituir Backbone.syncpara que ele passe automaticamente um indicador includeParamRoot para toJSON()criar, atualizar e corrigir:

//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]);
};

Aqui está o produto acabado:

//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);