diff --git a/lib/relation-definition.js b/lib/relation-definition.js index 2167ecb5..12669318 100644 --- a/lib/relation-definition.js +++ b/lib/relation-definition.js @@ -1503,6 +1503,7 @@ RelationDefinition.embedsMany = function embedsMany(modelFrom, modelTo, params) // validate all embedded items if (definition.options.validate) { modelFrom.validate(relationName, function(err) { + var self = this; var embeddedList = this[relationName] || []; var hasErrors = false; embeddedList.forEach(function(item) { @@ -1513,13 +1514,13 @@ RelationDefinition.embedsMany = function embedsMany(modelFrom, modelTo, params) var first = Object.keys(item.errors)[0]; var msg = 'contains invalid item: `' + id + '`'; msg += ' (' + first + ' ' + item.errors[first] + ')'; - this.errors.add(relationName, msg, 'invalid'); + self.errors.add(relationName, msg, 'invalid'); } } else { hasErrors = true; - this.errors.add(relationName, 'Contains invalid item', 'invalid'); + self.errors.add(relationName, 'Contains invalid item', 'invalid'); } - }.bind(this)); + }); if (hasErrors) err(false); }); } @@ -1751,16 +1752,14 @@ EmbedsMany.prototype.create = function (targetModelData, cb) { var err = inst.isValid() ? null : new ValidationError(inst); if (err) { - var index = embeddedList.indexOf(inst); - if (index > -1) embeddedList.splice(index, 1); - return process.nextTick(function() { - cb(err, embeddedList); + return process.nextTick(function() { + cb(err); }); } - modelInstance.updateAttribute(relationName, + modelInstance.updateAttribute(relationName, embeddedList, function(err, modelInst) { - cb(err, modelInst[relationName]); + cb(err, err ? null : inst); }); }; @@ -1952,6 +1951,12 @@ RelationDefinition.referencesMany = function referencesMany(modelFrom, modelTo, var updateByIdFunc = scopeMethods.updateById; modelFrom.prototype['__updateById__' + relationName] = updateByIdFunc; + var addFunc = scopeMethods.add; + modelFrom.prototype['__link__' + relationName] = addFunc; + + var removeFunc = scopeMethods.remove; + modelFrom.prototype['__unlink__' + relationName] = removeFunc; + scopeMethods.create = scopeMethod(definition, 'create'); scopeMethods.build = scopeMethod(definition, 'build'); @@ -2143,7 +2148,9 @@ ReferencesMany.prototype.add = function (acInst, cb) { var pk = this.definition.keyTo; var fk = this.definition.keyFrom; - var insertId = function(id, done) { + var insert = function(inst, done) { + var id = inst[pk]; + if (typeof id === 'object') { id = id.toString(); // mongodb } @@ -2156,13 +2163,13 @@ ReferencesMany.prototype.add = function (acInst, cb) { ids.push(id); } - modelInstance.updateAttribute(fk, ids, function(err, inst) { - done(err, inst[fk] || []); + modelInstance.updateAttribute(fk, ids, function(err) { + done(err, err ? null : inst); }); }; if (acInst instanceof modelTo) { - insertId(acInst[pk], cb); + insert(acInst, cb); } else { var filter = { where: {} }; filter.where[pk] = acInst; @@ -2170,8 +2177,8 @@ ReferencesMany.prototype.add = function (acInst, cb) { definition.applyScope(modelInstance, filter); modelTo.findOne(filter, function (err, inst) { - if (err || !inst) return cb(err, modelInstance[fk]); - insertId(inst[pk], cb); + if (err || !inst) return cb(err, null); + insert(inst, cb); }); } }; diff --git a/test/relations.test.js b/test/relations.test.js index 245b9bec..b6030dac 100644 --- a/test/relations.test.js +++ b/test/relations.test.js @@ -1255,12 +1255,11 @@ describe('relations', function () { it('should create embedded items on scope', function(done) { Person.create({ name: 'Fred' }, function(err, p) { - p.addressList.create({ street: 'Street 1' }, function(err, addresses) { + p.addressList.create({ street: 'Street 1' }, function(err, address) { should.not.exist(err); - addresses.should.have.length(1); - address1 = addresses[0]; + address1 = address; should.exist(address1.id); - addresses[0].street.should.equal('Street 1'); + address1.street.should.equal('Street 1'); done(); }); }); @@ -1268,13 +1267,9 @@ describe('relations', function () { it('should create embedded items on scope', function(done) { Person.findOne(function(err, p) { - p.addressList.create({ street: 'Street 2' }, function(err, addresses) { + p.addressList.create({ street: 'Street 2' }, function(err, address) { should.not.exist(err); - addresses.should.have.length(2); - address1 = addresses[0]; - address2 = addresses[1]; - should.exist(address1.id); - address1.street.should.equal('Street 1'); + address2 = address; should.exist(address2.id); address2.street.should.equal('Street 2'); done(); @@ -1310,11 +1305,11 @@ describe('relations', function () { it('should validate embedded items', function(done) { Person.findOne(function(err, p) { - p.addressList.create({}, function(err, addresses) { + p.addressList.create({}, function(err, address) { should.exist(err); + should.not.exist(address); err.name.should.equal('ValidationError'); err.details.codes.street.should.eql(['presence']); - addresses.should.have.length(2); done(); }); }); @@ -1428,12 +1423,10 @@ describe('relations', function () { Person.create({ name: 'Fred' }, function(err, p) { p.addressList.create({ id: 'home', street: 'Street 1' }, function(err, addresses) { should.not.exist(err); - p.addressList.create({ id: 'work', street: 'Work Street 2' }, function(err, addresses) { - addresses.should.have.length(2); - addresses[0].id.should.equal('home'); - addresses[0].street.should.equal('Street 1'); - addresses[1].id.should.equal('work'); - addresses[1].street.should.equal('Work Street 2'); + p.addressList.create({ id: 'work', street: 'Work Street 2' }, function(err, address) { + should.not.exist(err); + address.id.should.equal('work'); + address.street.should.equal('Work Street 2'); done(); }); }); @@ -1972,10 +1965,11 @@ describe('relations', function () { it('should add a record to scope - object', function (done) { Category.findOne(function(err, cat) { - cat.products.add(product1, function(err, ids) { + cat.products.add(product1, function(err, prod) { should.not.exist(err); cat.productIds.should.eql([product2.id, product1.id]); - ids.should.eql(cat.productIds); + prod.id.should.eql(product1.id); + prod.should.have.property('name'); done(); }); }); @@ -1983,11 +1977,12 @@ describe('relations', function () { it('should add a record to scope - object', function (done) { Category.findOne(function(err, cat) { - cat.products.add(product3.id, function(err, ids) { + cat.products.add(product3.id, function(err, prod) { should.not.exist(err); var expected = [product2.id, product1.id, product3.id]; cat.productIds.should.eql(expected); - ids.should.eql(cat.productIds); + prod.id.should.eql(product3.id); + prod.should.have.property('name'); done(); }); });