From e2d191aa8a07c965123e3ab7d1c989c9c1f917d3 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Sun, 22 Sep 2019 21:06:31 -0700 Subject: [PATCH] fix(discriminator): support `tiedValue` parameter for embedded discriminators analagous to top-level discriminators Fix #8164 --- lib/schema/SingleNestedPath.js | 4 ++-- lib/schema/documentarray.js | 4 ++-- test/model.discriminator.test.js | 40 ++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/lib/schema/SingleNestedPath.js b/lib/schema/SingleNestedPath.js index 9a2142f4159..3862529619c 100644 --- a/lib/schema/SingleNestedPath.js +++ b/lib/schema/SingleNestedPath.js @@ -283,8 +283,8 @@ SingleNestedPath.prototype.doValidateSync = function(value, scope, options) { * @api public */ -SingleNestedPath.prototype.discriminator = function(name, schema) { - discriminator(this.caster, name, schema); +SingleNestedPath.prototype.discriminator = function(name, schema, tiedValue) { + discriminator(this.caster, name, schema, tiedValue); this.caster.discriminators[name] = _createConstructor(schema, this.caster); diff --git a/lib/schema/documentarray.js b/lib/schema/documentarray.js index cce9026d776..9229676f77d 100644 --- a/lib/schema/documentarray.js +++ b/lib/schema/documentarray.js @@ -126,12 +126,12 @@ function _createConstructor(schema, options, baseClass) { * Ignore */ -DocumentArray.prototype.discriminator = function(name, schema) { +DocumentArray.prototype.discriminator = function(name, schema, tiedValue) { if (typeof name === 'function') { name = utils.getFunctionName(name); } - schema = discriminator(this.casterConstructor, name, schema); + schema = discriminator(this.casterConstructor, name, schema, tiedValue); const EmbeddedDocument = _createConstructor(schema, null, this.casterConstructor); EmbeddedDocument.baseCasterConstructor = this.casterConstructor; diff --git a/test/model.discriminator.test.js b/test/model.discriminator.test.js index 0155ad61824..eb25e0a3939 100644 --- a/test/model.discriminator.test.js +++ b/test/model.discriminator.test.js @@ -1080,6 +1080,46 @@ describe('model', function() { catch(done); }); + it('embedded with single nested subdocs and tied value (gh-8164)', function() { + const eventSchema = new Schema({ message: String }, + { discriminatorKey: 'kind', _id: false }); + + const trackSchema = new Schema({ event: eventSchema }); + trackSchema.path('event').discriminator('Clicked', new Schema({ + element: String + }, { _id: false }), 'click'); + trackSchema.path('event').discriminator('Purchased', new Schema({ + product: String + }, { _id: false }), 'purchase'); + + const MyModel = db.model('gh8164', trackSchema); + const doc1 = { + event: { + kind: 'click', + element: 'Amazon Link' + } + }; + const doc2 = { + event: { + kind: 'purchase', + product: 'Professional AngularJS' + } + }; + return MyModel.create([doc1, doc2]). + then(function(docs) { + const doc1 = docs[0]; + const doc2 = docs[1]; + + assert.equal(doc1.event.kind, 'click'); + assert.equal(doc1.event.element, 'Amazon Link'); + assert.ok(!doc1.event.product); + + assert.equal(doc2.event.kind, 'purchase'); + assert.equal(doc2.event.product, 'Professional AngularJS'); + assert.ok(!doc2.event.element); + }); + }); + it('Embedded discriminators in nested doc arrays (gh-6202)', function() { const eventSchema = new Schema({ message: String }, { discriminatorKey: 'kind',