Skip to content

Commit 3042ac1

Browse files
authored
Merge pull request #13958 from Automattic/vkarpov15/gh-13898
fix(schema): handle embedded discriminators defined using `Schema.prototype.discriminator()`
2 parents 03c6967 + 914b4b4 commit 3042ac1

File tree

4 files changed

+62
-13
lines changed

4 files changed

+62
-13
lines changed

lib/schema.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -723,19 +723,6 @@ Schema.prototype.add = function add(obj, prefix) {
723723
for (const key in val[0].discriminators) {
724724
schemaType.discriminator(key, val[0].discriminators[key]);
725725
}
726-
} else if (val[0] != null && val[0].instanceOfSchema && val[0]._applyDiscriminators instanceof Map) {
727-
const applyDiscriminators = val[0]._applyDiscriminators;
728-
const schemaType = this.path(prefix + key);
729-
for (const disc of applyDiscriminators.keys()) {
730-
schemaType.discriminator(disc, applyDiscriminators.get(disc));
731-
}
732-
}
733-
else if (val != null && val.instanceOfSchema && val._applyDiscriminators instanceof Map) {
734-
const applyDiscriminators = val._applyDiscriminators;
735-
const schemaType = this.path(prefix + key);
736-
for (const disc of applyDiscriminators.keys()) {
737-
schemaType.discriminator(disc, applyDiscriminators.get(disc));
738-
}
739726
}
740727
} else if (Object.keys(val).length < 1) {
741728
// Special-case: {} always interpreted as Mixed path so leaf at this node

lib/schema/SubdocumentPath.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ function SubdocumentPath(schema, path, options) {
5555
this.$isSingleNested = true;
5656
this.base = schema.base;
5757
SchemaType.call(this, path, options, 'Embedded');
58+
59+
if (schema._applyDiscriminators != null) {
60+
for (const disc of schema._applyDiscriminators.keys()) {
61+
this.discriminator(disc, schema._applyDiscriminators.get(disc));
62+
}
63+
}
5864
}
5965

6066
/*!

lib/schema/documentarray.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ function DocumentArrayPath(key, schema, options, schemaOptions) {
8888

8989
this.$embeddedSchemaType.caster = this.Constructor;
9090
this.$embeddedSchemaType.schema = this.schema;
91+
92+
if (schema._applyDiscriminators != null) {
93+
for (const disc of schema._applyDiscriminators.keys()) {
94+
this.discriminator(disc, schema._applyDiscriminators.get(disc));
95+
}
96+
}
9197
}
9298

9399
/**

test/document.test.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12520,6 +12520,56 @@ describe('document', function() {
1252012520
await doc.save();
1252112521
assert.strictEqual(attachmentSchemaPreValidateCalls, 1);
1252212522
});
12523+
12524+
it('handles embedded discriminators defined using Schema.prototype.discriminator (gh-13898)', async function() {
12525+
const baseNestedDiscriminated = new Schema({
12526+
type: { type: Number, required: true }
12527+
}, { discriminatorKey: 'type' });
12528+
12529+
class BaseClass {
12530+
whoAmI() {
12531+
return 'I am baseNestedDiscriminated';
12532+
}
12533+
}
12534+
BaseClass.type = 1;
12535+
12536+
baseNestedDiscriminated.loadClass(BaseClass);
12537+
12538+
class NumberTyped extends BaseClass {
12539+
whoAmI() {
12540+
return 'I am NumberTyped';
12541+
}
12542+
}
12543+
NumberTyped.type = 3;
12544+
12545+
class StringTyped extends BaseClass {
12546+
whoAmI() {
12547+
return 'I am StringTyped';
12548+
}
12549+
}
12550+
StringTyped.type = 4;
12551+
12552+
baseNestedDiscriminated.discriminator(1, new Schema({}).loadClass(NumberTyped));
12553+
baseNestedDiscriminated.discriminator('3', new Schema({}).loadClass(StringTyped));
12554+
12555+
const containsNestedSchema = new Schema({
12556+
nestedDiscriminatedTypes: { type: [baseNestedDiscriminated], required: true }
12557+
});
12558+
12559+
class ContainsNested {
12560+
whoAmI() {
12561+
return 'I am ContainsNested';
12562+
}
12563+
}
12564+
containsNestedSchema.loadClass(ContainsNested);
12565+
12566+
const Test = db.model('Test', containsNestedSchema);
12567+
const instance = await Test.create({ type: 1, nestedDiscriminatedTypes: [{ type: 1 }, { type: '3' }] });
12568+
assert.deepStrictEqual(
12569+
instance.nestedDiscriminatedTypes.map(i => i.whoAmI()),
12570+
['I am NumberTyped', 'I am StringTyped']
12571+
);
12572+
});
1252312573
});
1252412574

1252512575
describe('Check if instance function that is supplied in schema option is availabe', function() {

0 commit comments

Comments
 (0)