Skip to content

Commit 3ad5b4f

Browse files
authored
Merge pull request #14676 from Automattic/vkarpov15/gh-14675
fix(query): cast $pull using embedded discriminator schema when discriminator key is set in filter
2 parents 5b83806 + c639716 commit 3ad5b4f

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

lib/helpers/query/castUpdate.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ function walkUpdatePath(schema, obj, op, options, context, filter, pref) {
202202
// an update.
203203
if (op === '$pull') {
204204
schematype = schema._getSchema(prefix + key);
205+
if (schematype == null) {
206+
const _res = getEmbeddedDiscriminatorPath(schema, obj, filter, prefix + key, options);
207+
if (_res.schematype != null) {
208+
schematype = _res.schematype;
209+
}
210+
}
205211
if (schematype != null && schematype.schema != null) {
206212
obj[key] = cast(schematype.schema, obj[key], options, context);
207213
hasKeys = true;

test/model.updateOne.test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,6 +3017,37 @@ describe('model: updateOne: ', function() {
30173017
const doc = await Test.findById(_id);
30183018
assert.equal(doc.subdoc['1'], 'foobar');
30193019
});
3020+
it('handles embedded discriminators with $pull when discriminator key set in filter (gh-14675)', async function() {
3021+
const LoginSchema = new Schema({}, { discriminatorKey: 'type', _id: false });
3022+
const UserSchema = new Schema({
3023+
name: String,
3024+
login: LoginSchema
3025+
});
3026+
UserSchema.path('login').discriminator('ssh-key', new Schema({
3027+
keys: {
3028+
type: [{
3029+
id: { type: String, required: true },
3030+
publicKey: { type: String, required: true }
3031+
}],
3032+
default: []
3033+
}
3034+
}, { _id: false }));
3035+
const User = db.model('Test', UserSchema);
3036+
3037+
const { _id } = await User.create({
3038+
login: {
3039+
type: 'ssh-key',
3040+
keys: [{ id: 'my-key', publicKey: 'test' }, { id: 'test2', publicKey: 'foo' }]
3041+
}
3042+
});
3043+
const doc = await User.findOneAndUpdate(
3044+
{ _id, 'login.type': 'ssh-key' },
3045+
{ $pull: { 'login.keys': { id: 'my-key' } } },
3046+
{ new: true }
3047+
).exec();
3048+
assert.equal(doc.login.keys.length, 1);
3049+
assert.equal(doc.login.keys[0].id, 'test2');
3050+
});
30203051
});
30213052

30223053
async function delay(ms) {

0 commit comments

Comments
 (0)