From 01427b1755a7d403b504d52281f126b47507029d Mon Sep 17 00:00:00 2001 From: Janny Date: Fri, 13 Apr 2018 13:17:40 -0400 Subject: [PATCH] feat: omit default fn for embedsMany (#1532) * feat: omit default fn for embeds many * fix: apply feedback --- lib/relation-definition.js | 10 ++++-- test/relations.test.js | 65 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/lib/relation-definition.js b/lib/relation-definition.js index 63d72fe3..9234b772 100644 --- a/lib/relation-definition.js +++ b/lib/relation-definition.js @@ -2471,8 +2471,10 @@ RelationDefinition.embedsMany = function embedsMany(modelFrom, modelToRef, param var opts = Object.assign( params.options && params.options.property ? params.options.property : {}, + params.options && params.options.omitDefaultEmbeddedItem ? {type: [modelTo]} : { - type: [modelTo], default: function() { return []; }, + type: [modelTo], + default: function() { return []; }, } ); @@ -2920,9 +2922,8 @@ EmbedsMany.prototype.create = function(targetModelData, options, cb) { targetModelData = targetModelData || {}; cb = cb || utils.createPromiseCallback(); - var embeddedList = this.embeddedList(); - var inst = this.callScopeMethod('build', targetModelData); + var embeddedList = this.embeddedList(); var updateEmbedded = function(callback) { if (modelInstance.isNewRecord()) { @@ -2975,6 +2976,7 @@ EmbedsMany.prototype.build = function(targetModelData) { var modelInstance = this.modelInstance; var forceId = this.definition.options.forceId; var persistent = this.definition.options.persistent; + var propertyName = this.definition.keyFrom; var connector = modelTo.dataSource.connector; var pk = this.definition.keyTo; @@ -3008,8 +3010,10 @@ EmbedsMany.prototype.build = function(targetModelData) { if (this.definition.options.prepend) { embeddedList.unshift(inst); + modelInstance[propertyName] = embeddedList; } else { embeddedList.push(inst); + modelInstance[propertyName] = embeddedList; } this.prepareEmbeddedInstance(inst); diff --git a/test/relations.test.js b/test/relations.test.js index 6760bc9c..7a95a077 100644 --- a/test/relations.test.js +++ b/test/relations.test.js @@ -5021,6 +5021,71 @@ describe('relations', function() { }); }); + describe('embedsMany - omit default value for embedded item', function() { + before(function(done) { + tmp = getTransientDataSource({defaultIdType: Number}); + Person = db.define('Person', {name: String}); + Address = tmp.define('Address', {street: String}); + Address.validatesPresenceOf('street'); + + db.automigrate(['Person'], done); + }); + + it('can be declared', function(done) { + Person.embedsMany(Address, { + options: { + omitDefaultEmbeddedItem: true, + property: { + postgresql: { + dataType: 'json', + }, + }, + }, + }); + db.automigrate(['Person'], done); + }); + + it('should not set default value for embedded item', function() { + var p = new Person({name: 'Fred'}); + p.should.have.property('addresses', undefined); + }); + + it('should create embedded items on scope', function(done) { + Person.create({name: 'Fred'}, function(err, p) { + p.addressList.create({street: 'Street 1'}, function(err, address) { + if (err) return done(err); + should.exist(address.id); + address.street.should.equal('Street 1'); + p.addresses.should.be.array; + p.addresses.should.have.length(1); + done(); + }); + }); + }); + + it('should build embedded items', function(done) { + Person.findOne(function(err, p) { + p.addresses.should.have.length(1); + p.addressList.build({id: 'home', street: 'Home'}); + p.addressList.build({id: 'work', street: 'Work'}); + p.addresses.should.have.length(3); + done(); + }); + }); + + it('should not create embedded from attributes - relation name', function(done) { + var addresses = [ + {id: 'home', street: 'Home Street'}, + {id: 'work', street: 'Work Street'}, + ]; + Person.create({name: 'Wilma', addressList: addresses}, function(err, p) { + if (err) return done(err); + p.should.have.property('addresses', undefined); + done(); + }); + }); + }); + describe('embedsMany - numeric ids + forceId', function() { before(function(done) { tmp = getTransientDataSource();