Skip to content

Commit 636aa56

Browse files
committed
fix(model): handle discriminators in castObject()
1 parent 7ed441e commit 636aa56

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

lib/model.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3643,7 +3643,11 @@ Model.castObject = function castObject(obj, options) {
36433643
options = options || {};
36443644
const ret = {};
36453645

3646-
const schema = this.schema;
3646+
let schema = this.schema;
3647+
const discriminatorKey = schema.options.discriminatorKey;
3648+
if (schema.discriminators != null && obj != null && obj[discriminatorKey] != null) {
3649+
schema = getSchemaDiscriminatorByValue(schema, obj[discriminatorKey]) || schema;
3650+
}
36473651
const paths = Object.keys(schema.paths);
36483652

36493653
for (const path of paths) {

test/model.test.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7717,6 +7717,67 @@ describe('Model', function() {
77177717
const ret = Test.castObject(obj, { ignoreCastErrors: true });
77187718
assert.deepStrictEqual(ret, { nested: { num: 2 }, docArr: [{ num: 4 }] });
77197719
});
7720+
it('handles discriminators (gh-15075)', async function() {
7721+
// Create the base shape schema
7722+
const shapeSchema = new mongoose.Schema({ name: String }, {
7723+
discriminatorKey: 'kind',
7724+
_id: false
7725+
});
7726+
7727+
// Main schema with shape array
7728+
const schema = new mongoose.Schema({
7729+
shape: [shapeSchema]
7730+
});
7731+
7732+
// Circle discriminator
7733+
schema
7734+
.path('shape')
7735+
.discriminator('Circle', new mongoose.Schema({
7736+
radius: {
7737+
type: mongoose.Schema.Types.Number,
7738+
required: true
7739+
}
7740+
}, { _id: false }));
7741+
7742+
// PropertyPath schema for Square
7743+
const propertyPathSchema = new mongoose.Schema({
7744+
property: {
7745+
type: mongoose.Schema.Types.String,
7746+
required: true
7747+
},
7748+
path: {
7749+
type: mongoose.Schema.Types.String,
7750+
required: true
7751+
}
7752+
}, { _id: false });
7753+
7754+
// Square discriminator
7755+
schema
7756+
.path('shape')
7757+
.discriminator(
7758+
'Square',
7759+
new mongoose.Schema({
7760+
propertyPaths: {
7761+
type: [propertyPathSchema],
7762+
required: true
7763+
}
7764+
}, { _id: false })
7765+
);
7766+
7767+
const TestModel = db.model('Test', schema);
7768+
7769+
const circle = { shape: [{ kind: 'Circle', radius: '5' }] };
7770+
const square = { shape: [{ kind: 'Square', propertyPaths: [{ property: 42 }] }] };
7771+
7772+
assert.deepStrictEqual(
7773+
TestModel.castObject(circle).shape[0],
7774+
{ kind: 'Circle', radius: 5 }
7775+
);
7776+
assert.deepStrictEqual(
7777+
TestModel.castObject(square).shape[0],
7778+
{ kind: 'Square', propertyPaths: [{ property: '42' }] }
7779+
);
7780+
});
77207781
});
77217782

77227783
it('works if passing class that extends Document to `loadClass()` (gh-12254)', async function() {

0 commit comments

Comments
 (0)