Skip to content

Commit 8a7f2f2

Browse files
authored
Merge pull request #14011 from Automattic/vkarpov15/gh-13978
fix(schema): handle recursive schemas in discriminator definitions
2 parents 266804b + a5e4ec2 commit 8a7f2f2

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

lib/schema.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,9 @@ Schema.prototype._clone = function _clone(Constructor) {
412412
s.s.hooks = this.s.hooks.clone();
413413

414414
s.tree = clone(this.tree);
415-
s.paths = clone(this.paths);
415+
s.paths = Object.fromEntries(
416+
Object.entries(this.paths).map(([key, value]) => ([key, value.clone()]))
417+
);
416418
s.nested = clone(this.nested);
417419
s.subpaths = clone(this.subpaths);
418420
for (const schemaType of Object.values(s.paths)) {

lib/schema/SubdocumentPath.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function SubdocumentPath(schema, path, options) {
5656
this.base = schema.base;
5757
SchemaType.call(this, path, options, 'Embedded');
5858

59-
if (schema._applyDiscriminators != null) {
59+
if (schema._applyDiscriminators != null && !options?._skipApplyDiscriminators) {
6060
for (const disc of schema._applyDiscriminators.keys()) {
6161
this.discriminator(disc, schema._applyDiscriminators.get(disc));
6262
}
@@ -388,8 +388,11 @@ SubdocumentPath.prototype.toJSON = function toJSON() {
388388
*/
389389

390390
SubdocumentPath.prototype.clone = function() {
391-
const options = Object.assign({}, this.options);
392-
const schematype = new this.constructor(this.schema, this.path, options);
391+
const schematype = new this.constructor(
392+
this.schema,
393+
this.path,
394+
{ ...this.options, _skipApplyDiscriminators: true }
395+
);
393396
schematype.validators = this.validators.slice();
394397
if (this.requiredValidator !== undefined) {
395398
schematype.requiredValidator = this.requiredValidator;

test/schema.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,4 +3172,20 @@ describe('schema', function() {
31723172
const res = await Test.findOne({ _id: { $eq: doc._id, $type: 'objectId' } });
31733173
assert.equal(res.name, 'Test Testerson');
31743174
});
3175+
3176+
it('handles recursive definitions in discriminators (gh-13978)', function() {
3177+
const base = new Schema({
3178+
type: { type: Number, required: true }
3179+
}, { discriminatorKey: 'type' });
3180+
3181+
const recursive = new Schema({
3182+
self: { type: base, required: true }
3183+
});
3184+
3185+
base.discriminator(1, recursive);
3186+
const TestModel = db.model('gh13978', base);
3187+
3188+
const doc = new TestModel({ type: 1, self: { type: 1 } });
3189+
assert.strictEqual(doc.self.type, 1);
3190+
});
31753191
});

0 commit comments

Comments
 (0)