Skip to content

Commit 76c745c

Browse files
committed
fix: cast using overwritten embedded discriminator key when set
Fix Automattic#15051
1 parent 76f92d2 commit 76c745c

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

lib/helpers/query/getEmbeddedDiscriminatorPath.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ module.exports = function getEmbeddedDiscriminatorPath(schema, update, filter, p
2828
const updatedPathsByFilter = updatedPathsByArrayFilter(update);
2929

3030
for (let i = 0; i < parts.length; ++i) {
31-
const subpath = cleanPositionalOperators(parts.slice(0, i + 1).join('.'));
31+
const originalSubpath = parts.slice(0, i + 1).join('.');
32+
const subpath = cleanPositionalOperators(originalSubpath);
3233
schematype = schema.path(subpath);
3334
if (schematype == null) {
3435
continue;
@@ -56,6 +57,11 @@ module.exports = function getEmbeddedDiscriminatorPath(schema, update, filter, p
5657
discriminatorKey = filter[wrapperPath].$elemMatch[key];
5758
}
5859

60+
const discriminatorKeyUpdatePath = originalSubpath + '.' + key;
61+
if (discriminatorKeyUpdatePath in update) {
62+
discriminatorKey = update[discriminatorKeyUpdatePath];
63+
}
64+
5965
if (discriminatorValuePath in update) {
6066
discriminatorKey = update[discriminatorValuePath];
6167
}

test/model.updateOne.test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3091,6 +3091,57 @@ describe('model: updateOne: ', function() {
30913091
assert.equal(doc.login.keys.length, 1);
30923092
assert.equal(doc.login.keys[0].id, 'test2');
30933093
});
3094+
it('casts using overwritten discriminator key schema (gh-15051)', async function() {
3095+
const embedDiscriminatorSchema = new mongoose.Schema({
3096+
field1: String
3097+
});
3098+
const embedDiscriminatorSchema2 = new mongoose.Schema({
3099+
field2: String
3100+
});
3101+
const embedSchema = new mongoose.Schema({
3102+
field: String,
3103+
key: String
3104+
}, { discriminatorKey: 'key' });
3105+
embedSchema.discriminator('Type1', embedDiscriminatorSchema);
3106+
embedSchema.discriminator('Type2', embedDiscriminatorSchema2);
3107+
3108+
const testSchema = new mongoose.Schema({
3109+
testArray: [embedSchema]
3110+
});
3111+
3112+
const TestModel = db.model('Test', testSchema);
3113+
const test = new TestModel({
3114+
testArray: [{
3115+
key: 'Type1',
3116+
field: 'field',
3117+
field1: 'field1'
3118+
}]
3119+
});
3120+
await test.save();
3121+
3122+
const field2update = 'field2 update';
3123+
await TestModel.updateOne(
3124+
{ _id: test._id },
3125+
{
3126+
$set: {
3127+
'testArray.$[element].key': 'Type2',
3128+
'testArray.$[element].field2': field2update
3129+
}
3130+
},
3131+
{
3132+
arrayFilters: [
3133+
{
3134+
'element._id': test.testArray[0]._id
3135+
}
3136+
],
3137+
overwriteDiscriminatorKey: true
3138+
}
3139+
);
3140+
3141+
const r2 = await TestModel.findById(test._id);
3142+
assert.equal(r2.testArray[0].key, 'Type2');
3143+
assert.equal(r2.testArray[0].field2, field2update);
3144+
});
30943145
});
30953146

30963147
async function delay(ms) {

0 commit comments

Comments
 (0)