From 02915de25847a30bb1647bfa2e60aafd6ac8262f Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 1 Jan 2025 14:28:30 -0500 Subject: [PATCH] fix(schema): allow multiple self-referencing discriminator schemas using Schema.prototype.discriminator Fix #15120 --- lib/schema/documentArray.js | 1 + lib/schema/subdocument.js | 1 + test/model.test.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/lib/schema/documentArray.js b/lib/schema/documentArray.js index 9a7a5d3181d..413dc4a8fbc 100644 --- a/lib/schema/documentArray.js +++ b/lib/schema/documentArray.js @@ -522,6 +522,7 @@ SchemaDocumentArray.prototype.clone = function() { } schematype.Constructor.discriminators = Object.assign({}, this.Constructor.discriminators); + schematype._appliedDiscriminators = this._appliedDiscriminators; return schematype; }; diff --git a/lib/schema/subdocument.js b/lib/schema/subdocument.js index 5116ed0cfa8..9a77d82c879 100644 --- a/lib/schema/subdocument.js +++ b/lib/schema/subdocument.js @@ -393,5 +393,6 @@ SchemaSubdocument.prototype.clone = function() { schematype.requiredValidator = this.requiredValidator; } schematype.caster.discriminators = Object.assign({}, this.caster.discriminators); + schematype._appliedDiscriminators = this._appliedDiscriminators; return schematype; }; diff --git a/test/model.test.js b/test/model.test.js index 119e4d63485..e6a1ef9cd3e 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -8004,6 +8004,36 @@ describe('Model', function() { assert.equal(doc.items[0].prop, 42); }); + it('does not throw with multiple self-referencing discriminator schemas applied to schema (gh-15120)', async function() { + const baseSchema = new Schema({ + type: { type: Number, required: true } + }, { discriminatorKey: 'type' }); + + const selfRefSchema = new Schema({ + self: { type: [baseSchema] } + }); + + const anotherSelfRefSchema = new Schema({ + self2: { type: [baseSchema] } + }); + + baseSchema.discriminator(5, selfRefSchema); + baseSchema.discriminator(6, anotherSelfRefSchema); + const Test = db.model('Test', baseSchema); + + const doc = await Test.create({ + type: 5, + self: { + type: 6, + self2: null + } + }); + assert.strictEqual(doc.type, 5); + assert.equal(doc.self.length, 1); + assert.strictEqual(doc.self[0].type, 6); + assert.strictEqual(doc.self[0].self2, null); + }); + it('inserts versionKey even if schema has `toObject.versionKey` set to false (gh-14344)', async function() { const schema = new mongoose.Schema( { name: String },