Skip to content

Commit

Permalink
fix(model): handle discriminators in castObject()
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Dec 15, 2024
1 parent 7ed441e commit 636aa56
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -3643,7 +3643,11 @@ Model.castObject = function castObject(obj, options) {
options = options || {};
const ret = {};

const schema = this.schema;
let schema = this.schema;
const discriminatorKey = schema.options.discriminatorKey;
if (schema.discriminators != null && obj != null && obj[discriminatorKey] != null) {
schema = getSchemaDiscriminatorByValue(schema, obj[discriminatorKey]) || schema;
}
const paths = Object.keys(schema.paths);

for (const path of paths) {
Expand Down
61 changes: 61 additions & 0 deletions test/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7717,6 +7717,67 @@ describe('Model', function() {
const ret = Test.castObject(obj, { ignoreCastErrors: true });
assert.deepStrictEqual(ret, { nested: { num: 2 }, docArr: [{ num: 4 }] });
});
it('handles discriminators (gh-15075)', async function() {
// Create the base shape schema
const shapeSchema = new mongoose.Schema({ name: String }, {
discriminatorKey: 'kind',
_id: false
});

// Main schema with shape array
const schema = new mongoose.Schema({
shape: [shapeSchema]
});

// Circle discriminator
schema
.path('shape')
.discriminator('Circle', new mongoose.Schema({
radius: {
type: mongoose.Schema.Types.Number,
required: true
}
}, { _id: false }));

// PropertyPath schema for Square
const propertyPathSchema = new mongoose.Schema({
property: {
type: mongoose.Schema.Types.String,
required: true
},
path: {
type: mongoose.Schema.Types.String,
required: true
}
}, { _id: false });

// Square discriminator
schema
.path('shape')
.discriminator(
'Square',
new mongoose.Schema({
propertyPaths: {
type: [propertyPathSchema],
required: true
}
}, { _id: false })
);

const TestModel = db.model('Test', schema);

const circle = { shape: [{ kind: 'Circle', radius: '5' }] };
const square = { shape: [{ kind: 'Square', propertyPaths: [{ property: 42 }] }] };

assert.deepStrictEqual(
TestModel.castObject(circle).shape[0],
{ kind: 'Circle', radius: 5 }
);
assert.deepStrictEqual(
TestModel.castObject(square).shape[0],
{ kind: 'Square', propertyPaths: [{ property: '42' }] }
);
});
});

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

0 comments on commit 636aa56

Please sign in to comment.