From aa5943f6b022ce59a8b9a861d93340e485b492e6 Mon Sep 17 00:00:00 2001 From: Fabien Franzen Date: Tue, 24 Mar 2015 15:35:56 +0100 Subject: [PATCH] Properly support embedsMany destroyAll --- lib/relation-definition.js | 29 +++++++++++++++++++++++++++ lib/scope.js | 3 ++- test/relations.test.js | 41 +++++++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/lib/relation-definition.js b/lib/relation-definition.js index 567a0636..ca4e8945 100644 --- a/lib/relation-definition.js +++ b/lib/relation-definition.js @@ -2106,6 +2106,10 @@ RelationDefinition.embedsMany = function embedsMany(modelFrom, modelTo, params) scopeMethods.related = scopeMethod(definition, 'related'); // bound to definition + if (!definition.options.persistent) { + scopeMethods.destroyAll = scopeMethod(definition, 'destroyAll'); + } + var customMethods = extendScopeMethods(definition, scopeMethods, params.scopeMethods); for (var i = 0; i < customMethods.length; i++) { @@ -2312,6 +2316,31 @@ EmbedsMany.prototype.destroyById = function (fkId, cb) { return inst; // sync }; +EmbedsMany.prototype.destroyAll = function(where, cb) { + if (typeof where === 'function') cb = where, where = {}; + var propertyName = this.definition.keyFrom; + var modelInstance = this.modelInstance; + + var embeddedList = this.embeddedList(); + + if (where && Object.keys(where).length > 0) { + var filter = applyFilter({ where: where }); + var reject = function(v) { return !filter(v) }; + embeddedList = embeddedList ? embeddedList.filter(reject) : embeddedList; + } else { + embeddedList = []; + } + + if (typeof cb === 'function') { + modelInstance.updateAttribute(propertyName, + embeddedList, function(err) { + cb(err); + }); + } else { + modelInstance.setAttribute(propertyName, embeddedList); + } +}; + EmbedsMany.prototype.get = EmbedsMany.prototype.findById; EmbedsMany.prototype.set = EmbedsMany.prototype.updateById; EmbedsMany.prototype.unset = EmbedsMany.prototype.destroyById; diff --git a/lib/scope.js b/lib/scope.js index a4e17f74..519a027f 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -192,10 +192,11 @@ function defineScope(cls, targetClass, name, params, methods, options) { f.findById = findById; f.findOne = findOne; f.count = count; + for (var i in definition.methods) { f[i] = definition.methods[i].bind(self); } - + if (!targetClass) return f; // Define scope-chaining, such as diff --git a/test/relations.test.js b/test/relations.test.js index 638e537d..9cebef96 100644 --- a/test/relations.test.js +++ b/test/relations.test.js @@ -2665,13 +2665,52 @@ describe('relations', function () { }); }); - it('should have embedded items - verify', function(done) { + it('should have removed embedded items - verify', function(done) { Person.findOne(function(err, p) { p.addresses.should.have.length(1); done(); }); }); + it('should create embedded items on scope', function(done) { + Person.findOne(function(err, p) { + p.addressList.create({ street: 'Street 3' }, function(err, address) { + should.not.exist(err); + address.street.should.equal('Street 3'); + done(); + }); + }); + }); + + it('should remove embedded items - filtered', function(done) { + Person.findOne(function(err, p) { + p.addresses.should.have.length(2); + p.addressList.destroyAll({ street: 'Street 3' }, function(err) { + should.not.exist(err); + p.addresses.should.have.length(1); + done(); + }); + }); + }); + + it('should remove all embedded items', function(done) { + Person.findOne(function(err, p) { + p.addresses.should.have.length(1); + p.addressList.destroyAll(function(err) { + should.not.exist(err); + p.addresses.should.have.length(0); + done(); + }); + }); + }); + + it('should have removed all embedded items - verify', function(done) { + Person.findOne(function(err, p) { + p.addresses.should.have.length(0); + done(); + }); + }); + }); describe('embedsMany - numeric ids + forceId', function () {