Skip to content

Commit 965b7d5

Browse files
committed
fix(populate): call transform object with single id instead of array when populating a justOne path under an array
Fix #14073
1 parent 7584ffd commit 965b7d5

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

lib/helpers/populate/assignVals.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ module.exports = function assignVals(o) {
8080
return valueFilter(val[0], options, populateOptions, _allIds);
8181
} else if (o.justOne === false && !Array.isArray(val)) {
8282
return valueFilter([val], options, populateOptions, _allIds);
83+
} else if (o.justOne === true && !Array.isArray(val) && Array.isArray(_allIds)) {
84+
return valueFilter(val, options, populateOptions, val == null ? val : _allIds[o.rawOrder[val._id]]);
8385
}
8486
return valueFilter(val, options, populateOptions, _allIds);
8587
}

test/model.populate.test.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10776,4 +10776,59 @@ describe('model: populate:', function() {
1077610776
new Date('2015-06-01').toString()
1077710777
);
1077810778
});
10779+
10780+
it('calls transform with single ObjectId when populating justOne path underneath array (gh-14073)', async function() {
10781+
const mySchema = mongoose.Schema({
10782+
name: { type: String },
10783+
items: [{
10784+
_id: false,
10785+
name: { type: String },
10786+
brand: { type: mongoose.Schema.Types.ObjectId, ref: 'Brand' }
10787+
}]
10788+
});
10789+
10790+
const brandSchema = mongoose.Schema({
10791+
name: 'String',
10792+
quantity: Number
10793+
});
10794+
10795+
const myModel = db.model('MyModel', mySchema);
10796+
const brandModel = db.model('Brand', brandSchema);
10797+
const { _id: id1 } = await brandModel.create({
10798+
name: 'test',
10799+
quantity: 1
10800+
});
10801+
const { _id: id2 } = await brandModel.create({
10802+
name: 'test1',
10803+
quantity: 1
10804+
});
10805+
const { _id: id3 } = await brandModel.create({
10806+
name: 'test2',
10807+
quantity: 2
10808+
});
10809+
const brands = await brandModel.find();
10810+
const test = new myModel({ name: 'Test Model' });
10811+
for (let i = 0; i < brands.length; i++) {
10812+
test.items.push({ name: `${i}`, brand: brands[i]._id });
10813+
}
10814+
await test.save();
10815+
10816+
const ids = [];
10817+
await myModel
10818+
.findOne()
10819+
.populate([
10820+
{
10821+
path: 'items.brand',
10822+
transform: (doc, id) => {
10823+
ids.push(id);
10824+
return doc;
10825+
}
10826+
}
10827+
]);
10828+
assert.equal(ids.length, 3);
10829+
assert.deepStrictEqual(
10830+
ids.map(id => id.toHexString()),
10831+
[id1.toString(), id2.toString(), id3.toString()]
10832+
);
10833+
});
1077910834
});

0 commit comments

Comments
 (0)