From 1d5079d8113f3a0d0b61d900766d0102f0b44f0c Mon Sep 17 00:00:00 2001 From: Fabien Franzen Date: Wed, 20 Aug 2014 15:37:40 +0200 Subject: [PATCH] Implement update() on embedsOne scope --- lib/relation-definition.js | 30 +++++++++++++++++++++++++++++- test/relations.test.js | 22 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/relation-definition.js b/lib/relation-definition.js index b0378a4c..7a9a1d31 100644 --- a/lib/relation-definition.js +++ b/lib/relation-definition.js @@ -1625,6 +1625,7 @@ RelationDefinition.embedsOne = function (modelFrom, modelTo, params) { var relationMethod = relation.related.bind(relation) relationMethod.create = relation.create.bind(relation); relationMethod.build = relation.build.bind(relation); + relationMethod.update = relation.update.bind(relation); relationMethod.destroy = relation.destroy.bind(relation); relationMethod._targetClass = definition.modelTo.modelName; return relationMethod; @@ -1705,12 +1706,39 @@ EmbedsOne.prototype.create = function (targetModelData, cb) { EmbedsOne.prototype.build = function (targetModelData) { var modelTo = this.definition.modelTo; var modelInstance = this.modelInstance; + var propertyName = this.definition.keyFrom; targetModelData = targetModelData || {}; this.definition.applyProperties(modelInstance, targetModelData); - return new modelTo(targetModelData); + var embeddedInstance = new modelTo(targetModelData); + modelInstance[propertyName] = embeddedInstance; + + return embeddedInstance; +}; + +EmbedsOne.prototype.update = function (targetModelData, cb) { + var modelTo = this.definition.modelTo; + var modelInstance = this.modelInstance; + var propertyName = this.definition.keyFrom; + + var isInst = targetModelData instanceof ModelBaseClass; + var data = isInst ? targetModelData.toObject() : targetModelData; + + var embeddedInstance = modelInstance[propertyName]; + if (embeddedInstance instanceof modelTo) { + embeddedInstance.setAttributes(data); + if (typeof cb === 'function') { + modelInstance.save(function(err, inst) { + cb(err, inst ? inst[propertyName] : embeddedInstance); + }); + } + } else if (!embeddedInstance && cb) { + this.create(data, db); + } else if (!embeddedInstance) { + this.build(data); + } }; EmbedsOne.prototype.destroy = function (cb) { diff --git a/test/relations.test.js b/test/relations.test.js index 55f0ae58..cd522018 100644 --- a/test/relations.test.js +++ b/test/relations.test.js @@ -1426,6 +1426,28 @@ describe('relations', function () { }); }); + it('should update an embedded item on scope', function(done) { + Person.findById(personId, function(err, p) { + p.passportItem.update({name: 'Freddy'}, function(err, passport) { + should.not.exist(err); + var passport = p.passportItem(); + passport.toObject().should.eql({name: 'Freddy'}); + passport.should.be.an.instanceOf(Passport); + passport.should.equal(p.passport); + done(); + }); + }); + }); + + it('should get an embedded item on scope - verify', function(done) { + Person.findById(personId, function(err, p) { + should.not.exist(err); + var passport = p.passportItem(); + passport.toObject().should.eql({name: 'Freddy'}); + done(); + }); + }); + it('should destroy an embedded item on scope', function(done) { Person.findById(personId, function(err, p) { p.passportItem.destroy(function(err) {