Skip to content

Commit

Permalink
Merge pull request #12193 from Automattic/vkarpov15/gh-12143
Browse files Browse the repository at this point in the history
fix(model+query): handle populate with lean transform that deletes `_id`
  • Loading branch information
vkarpov15 committed Aug 3, 2022
2 parents 7ed781c + 16bec60 commit 07e36aa
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
19 changes: 19 additions & 0 deletions lib/model.js
Expand Up @@ -4599,6 +4599,17 @@ function populate(model, docs, options, callback) {
mod.options.options.sort || void 0;
assignmentOpts.excludeId = excludeIdReg.test(select) || (select && select._id === 0);

// Lean transform may delete `_id`, which would cause assignment
// to fail. So delay running lean transform until _after_
// `_assign()`
if (mod.options &&
mod.options.options &&
mod.options.options.lean &&
mod.options.options.lean.transform) {
mod.options.options._leanTransform = mod.options.options.lean.transform;
mod.options.options.lean = true;
}

if (ids.length === 0 || ids.every(utils.isNullOrUndefined)) {
// Ensure that we set to 0 or empty array even
// if we don't actually execute a query to make sure there's a value
Expand Down Expand Up @@ -4673,6 +4684,14 @@ function populate(model, docs, options, callback) {
for (const arr of params) {
removeDeselectedForeignField(arr[0].foreignField, arr[0].options, vals);
}
for (const arr of params) {
const mod = arr[0];
if (mod.options && mod.options.options && mod.options.options._leanTransform) {
for (const doc of vals) {
mod.options.options._leanTransform(doc);
}
}
}
callback();
}
}
Expand Down
38 changes: 36 additions & 2 deletions test/query.test.js
Expand Up @@ -3992,7 +3992,7 @@ describe('Query', function() {
});
});

it('allows a transform option for lean on a query gh-10423', async function() {
it('allows a transform option for lean on a query (gh-10423)', async function() {
const arraySchema = new mongoose.Schema({
sub: String
});
Expand All @@ -4004,7 +4004,7 @@ describe('Query', function() {
foo: [arraySchema],
otherName: subDoc
});
const Test = db.model('gh10423', testSchema);
const Test = db.model('Test', testSchema);
await Test.create({ name: 'foo', foo: [{ sub: 'Test' }, { sub: 'Testerson' }], otherName: { nickName: 'Bar' } });

const result = await Test.find().lean({
Expand All @@ -4030,6 +4030,40 @@ describe('Query', function() {
assert.strictEqual(single.foo[0]._id, undefined);
});

it('handles a lean transform that deletes _id with populate (gh-12143) (gh-10423)', async function() {
const testSchema = Schema({
name: String,
user: {
type: mongoose.Types.ObjectId,
ref: 'User'
}
});

const userSchema = Schema({
name: String
});

const Test = db.model('Test', testSchema);
const User = db.model('User', userSchema);

const user = await User.create({ name: 'John Smith' });
let test = await Test.create({ name: 'test', user });

test = await Test.findById(test).populate('user').lean({
transform: (doc) => {
delete doc._id;
delete doc.__v;
return doc;
}
});

assert.ok(test);
assert.deepStrictEqual(test, {
name: 'test',
user: { name: 'John Smith' }
});
});

it('skips applying default projections over slice projections (gh-11940)', async function() {
const commentSchema = new mongoose.Schema({
comment: String
Expand Down

0 comments on commit 07e36aa

Please sign in to comment.