Skip to content

Commit

Permalink
Merge pull request #14135 from Automattic/vkarpov15/gh-14073
Browse files Browse the repository at this point in the history
Call transform object with single id instead of array when populating a justOne path under an array
  • Loading branch information
vkarpov15 committed Dec 3, 2023
2 parents 778d8de + 0282f50 commit 2d65e00
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lib/helpers/populate/assignVals.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ module.exports = function assignVals(o) {
const options = o.options;
const count = o.count && o.isVirtual;
let i;
let setValueIndex = 0;

function setValue(val) {
++setValueIndex;
if (count) {
return val;
}
Expand Down Expand Up @@ -80,11 +82,14 @@ module.exports = function assignVals(o) {
return valueFilter(val[0], options, populateOptions, _allIds);
} else if (o.justOne === false && !Array.isArray(val)) {
return valueFilter([val], options, populateOptions, _allIds);
} else if (o.justOne === true && !Array.isArray(val) && Array.isArray(_allIds)) {
return valueFilter(val, options, populateOptions, val == null ? val : _allIds[setValueIndex - 1]);
}
return valueFilter(val, options, populateOptions, _allIds);
}

for (i = 0; i < docs.length; ++i) {
setValueIndex = 0;
const _path = o.path.endsWith('.$*') ? o.path.slice(0, -3) : o.path;
const existingVal = mpath.get(_path, docs[i], lookupLocalFields);
if (existingVal == null && !getVirtual(o.originalModel.schema, _path)) {
Expand Down
58 changes: 58 additions & 0 deletions test/model.populate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10776,4 +10776,62 @@ describe('model: populate:', function() {
new Date('2015-06-01').toString()
);
});

it('calls transform with single ObjectId when populating justOne path underneath array (gh-14073)', async function() {
const mySchema = mongoose.Schema({
name: { type: String },
items: [{
_id: false,
name: { type: String },
brand: { type: mongoose.Schema.Types.ObjectId, ref: 'Brand' }
}]
});

const brandSchema = mongoose.Schema({
name: 'String',
quantity: Number
});

const myModel = db.model('MyModel', mySchema);
const brandModel = db.model('Brand', brandSchema);
const { _id: id1 } = await brandModel.create({
name: 'test',
quantity: 1
});
const { _id: id2 } = await brandModel.create({
name: 'test1',
quantity: 1
});
const { _id: id3 } = await brandModel.create({
name: 'test2',
quantity: 2
});
const brands = await brandModel.find();
const test = new myModel({ name: 'Test Model' });
for (let i = 0; i < brands.length; i++) {
test.items.push({ name: `${i}`, brand: brands[i]._id });
}

const id4 = new mongoose.Types.ObjectId();
test.items.push({ name: '4', brand: id4 });
await test.save();

const ids = [];
await myModel
.findOne()
.populate([
{
path: 'items.brand',
transform: (doc, id) => {
ids.push(id);
return doc;
}
}
]);
assert.equal(ids.length, 4);
assert.deepStrictEqual(
ids.map(id => id?.toHexString()),
[id1.toString(), id2.toString(), id3.toString(), id4.toString()]
);
});
});

0 comments on commit 2d65e00

Please sign in to comment.