Skip to content
This repository has been archived by the owner on Apr 5, 2019. It is now read-only.

Commit

Permalink
Added support for scoped urlRoots for models
Browse files Browse the repository at this point in the history
  • Loading branch information
bjpirt committed May 15, 2012
1 parent e48e539 commit 571e3db
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 8 deletions.
17 changes: 11 additions & 6 deletions backbone-postgresql.js
Expand Up @@ -19,6 +19,7 @@ _ = require('underscore');
model.load_attributes(function(){ model.load_attributes(function(){
con.connect(function(err, client){ con.connect(function(err, client){
var attr_query = (model.has_attributes() ? ', %# attributes as attributes' : ''); var attr_query = (model.has_attributes() ? ', %# attributes as attributes' : '');
options.relation_conds = model.relation_conds();
var filter = model.filter_query(options, ' AND '); var filter = model.filter_query(options, ' AND ');
client.query('SELECT *' + attr_query + ' FROM ' + model.table_name() + ' WHERE id = $1' + filter, [model.id], function(err, result) { client.query('SELECT *' + attr_query + ' FROM ' + model.table_name() + ' WHERE id = $1' + filter, [model.id], function(err, result) {
if(err) return options.error(model, err); if(err) return options.error(model, err);
Expand All @@ -38,6 +39,7 @@ _ = require('underscore');
var dollars = []; var dollars = [];
var hstore_attrs = {}; var hstore_attrs = {};
var dollar_counter = 1; var dollar_counter = 1;
_.extend(model.attributes, model.relation_conds());
for(var key in model.attributes){ for(var key in model.attributes){
if(existing_keys.indexOf(key) != -1){ if(existing_keys.indexOf(key) != -1){
keys.push(key); keys.push(key);
Expand Down Expand Up @@ -104,7 +106,9 @@ _ = require('underscore');


delete: function(model, options){ delete: function(model, options){
con.connect(function(err, client){ con.connect(function(err, client){
client.query('DELETE FROM ' + model.table_name() + ' WHERE id = $1 RETURNING id', [model.id], function(err, result) { options.relation_conds = model.relation_conds()
var where_clause = model.filter_query(options, ' AND ')
client.query('DELETE FROM ' + model.table_name() + ' WHERE id = $1' + where_clause + ' RETURNING id', [model.id], function(err, result) {
if(err) return options.error(model, err); if(err) return options.error(model, err);
if(result.rows.length == 0) return options.error(model, new Error("Not found")); if(result.rows.length == 0) return options.error(model, new Error("Not found"));
options.success(); options.success();
Expand All @@ -116,7 +120,7 @@ _ = require('underscore');
con.connect(function(err, client){ con.connect(function(err, client){
var model = new collection.model(); var model = new collection.model();
model.load_attributes(function(){ model.load_attributes(function(){
options.relation_filter = collection.filter_params(); options.relation_conds = collection.relation_conds();
var where_clause = model.filter_query(options, ' WHERE '); var where_clause = model.filter_query(options, ' WHERE ');
client.query('SELECT * FROM ' + collection.table_name() + where_clause + ' ORDER BY id', [], function(err, result) { client.query('SELECT * FROM ' + collection.table_name() + where_clause + ' ORDER BY id', [], function(err, result) {
if(err) return options.error(collection, err); if(err) return options.error(collection, err);
Expand Down Expand Up @@ -243,16 +247,16 @@ _ = require('underscore');
conds = _.keys(options.filter).map(function(i){ return i + ' = ' + self.quote(i, options.filter[i]) }); conds = _.keys(options.filter).map(function(i){ return i + ' = ' + self.quote(i, options.filter[i]) });
} }
} }
if('relation_filter' in options){ if('relation_conds' in options){
conds = conds.concat(_.keys(options.relation_filter).map(function(i){ return i + ' = ' + self.quote(i, options.relation_filter[i]) })); conds = conds.concat(_.keys(options.relation_conds).map(function(i){ return i + ' = ' + self.quote(i, options.relation_conds[i]) }));
} }
if(conds.length == 0) return ''; if(conds.length == 0) return '';
return prefix + conds.join(' AND '); return prefix + conds.join(' AND ');
} }


var old_fn = Backbone.Collection.prototype._onModelEvent; var old_fn = Backbone.Collection.prototype._onModelEvent;
Backbone.Collection.prototype._onModelEvent = function(ev, model, collection, options) { Backbone.Collection.prototype._onModelEvent = function(ev, model, collection, options) {
if (ev == 'add') _.extend(model.attributes, collection.filter_params()); if (ev == 'add') _.extend(model.attributes, collection.relation_conds());
old_fn(ev, model, collection, options); old_fn(ev, model, collection, options);
} }


Expand All @@ -261,14 +265,15 @@ _ = require('underscore');
return split_url[split_url.length - 1]; return split_url[split_url.length - 1];
} }


Backbone.Collection.prototype.filter_params = function(){ Backbone.Collection.prototype.relation_conds = function(){
var split_url = _.reject(this.urlRoot.split('/'), function(elem){ return elem === ''}); var split_url = _.reject(this.urlRoot.split('/'), function(elem){ return elem === ''});
var res = {}; var res = {};
if(split_url.length == 3){ if(split_url.length == 3){
res[split_url[0] + '_id'] = parseInt(split_url[1]); res[split_url[0] + '_id'] = parseInt(split_url[1]);
} }
return res; return res;
} }
Backbone.Model.prototype.relation_conds = Backbone.Collection.prototype.relation_conds;


Backbone.Model.prototype.sync = function(method, model, options){ Backbone.Model.prototype.sync = function(method, model, options){
return con[method](model, options); return con[method](model, options);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -11,7 +11,7 @@
}, },
"main": "backbone-postgresql.js", "main": "backbone-postgresql.js",
"scripts": { "scripts": {
"test": "./node_modules/mocha/bin/mocha test/*_test.js" "test": "./node_modules/mocha/bin/mocha -R spec test/*_test.js"
}, },
"dependencies": { "dependencies": {
"backbone":"0.9.2", "backbone":"0.9.2",
Expand Down
38 changes: 38 additions & 0 deletions test/basics_test.js
Expand Up @@ -211,6 +211,44 @@ describe('Backbone PostgreSQL storage adaptor', function() {
done(); done();
}}); }});
}); });

it('should allow further filters to be placed on the destroy using an object', function(done){
var test_model = new Test({one: 'testone', two: 2});
test_model.save(null, {success: function(){
test_model.destroy({ filter: {two: 3},
error: function(model, err){
err.message.should.eql('Not found');
test_model.destroy({ filter: {two: 2},
success: function(deleted_model){
client.query("SELECT * FROM " + table_name + " WHERE id = $1", [test_model.id], function(err, result) {
result.rows.length.should.eql(0);
done();
});
}
});
}
});
}});
});

it('should allow further filters to be placed on the destroy using an array', function(done){
var test_model = new Test({one: 'testone', two: 2});
test_model.save(null, {success: function(){
test_model.destroy({ filter: ["two = 3"],
error: function(model, err){
err.message.should.eql('Not found');
test_model.destroy({ filter: ["two = 2"],
success: function(deleted_model){
client.query("SELECT * FROM " + table_name + " WHERE id = $1", [test_model.id], function(err, result) {
result.rows.length.should.eql(0);
done();
});
}
});
}
});
}});
});
}); });
}); });


Expand Down
45 changes: 44 additions & 1 deletion test/relations_test.js
Expand Up @@ -99,7 +99,50 @@ describe('Backbone PostgreSQL storage adaptor relations', function() {
}); });
}); });


}); describe('using a model with a nested urlRoot', function(){
it('should be saved with the correct foreign key', function(done){
var model = new Test();
model.urlRoot = '/reltest/2/' + table_name;
should.not.exist(model.attributes.reltest_id);
model.save(null, {success: function(){
model.attributes.reltest_id.should.eql(2);
model.url().should.eql('/reltest/2/' + table_name + '/' + model.id);
done();
}});
});


it('should be scoped properly when fetching the model', function(done){
test1 = new Test({reltest_id: 1, one: 'a'});
test1.save(null, {success: function(){
var model = new Test({id: test1.id});
model.urlRoot = '/reltest/1/' + table_name;
model.fetch({success: function(){
model.id.should.eql(test1.id);
model.urlRoot = '/reltest/2/' + table_name;
model.fetch({error: function(model, err){
err.message.should.eql('Not found');
done();
}});
}});
}});
});

it('should be scoped properly when destroying the model', function(done){
test1 = new Test({reltest_id: 1, one: 'a'});
test1.save(null, {success: function(){
var model = new Test({id: test1.id});
model.urlRoot = '/reltest/2/' + table_name;
model.destroy({error: function(m, err){
err.message.should.eql('Not found');
model.urlRoot = '/reltest/1/' + table_name;
model.destroy({success: function(){
done();
}});
}});
}});
});

});
});
}); });


0 comments on commit 571e3db

Please sign in to comment.