Skip to content

Commit

Permalink
fix(populate): call setter on virtual populated path with populated d…
Browse files Browse the repository at this point in the history
…oc instead of undefined

Fix #14285
  • Loading branch information
vkarpov15 committed Feb 1, 2024
1 parent 8ef0d9a commit 9739dfc
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 8 deletions.
18 changes: 10 additions & 8 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -2288,28 +2288,30 @@ Schema.prototype.virtual = function(name, options) {
virtual.options = options;

virtual.
set(function(_v) {
set(function(v) {
if (!this.$$populatedVirtuals) {
this.$$populatedVirtuals = {};
}

if (options.justOne || options.count) {
this.$$populatedVirtuals[name] = Array.isArray(_v) ?
_v[0] :
_v;
this.$$populatedVirtuals[name] = Array.isArray(v) ?
v[0] :
v;

if (typeof this.$$populatedVirtuals[name] !== 'object') {
this.$$populatedVirtuals[name] = options.count ? _v : null;
this.$$populatedVirtuals[name] = options.count ? v : null;
}
} else {
this.$$populatedVirtuals[name] = Array.isArray(_v) ?
_v :
_v == null ? [] : [_v];
this.$$populatedVirtuals[name] = Array.isArray(v) ?
v :
v == null ? [] : [v];

this.$$populatedVirtuals[name] = this.$$populatedVirtuals[name].filter(function(doc) {
return doc && typeof doc === 'object';
});
}

return this.$$populatedVirtuals[name];
});

if (typeof options.get === 'function') {
Expand Down
54 changes: 54 additions & 0 deletions test/model.populate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10868,4 +10868,58 @@ describe('model: populate:', function() {
{ name: 'foo', prop: 'bar' }
);
});

it('calls setter on virtual populated path with populated doc (gh-14285)', async function() {
const userSchema = new Schema({
email: String,
name: 'String'
});

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

const user = await User.create({
email: 'admin@example.com',
name: 'Admin'
});

const personSchema = new Schema({
userId: ObjectId,
userType: String
});

personSchema.
virtual('user', {
ref() {
return this.userType;
},
localField: 'userId',
foreignField: '_id',
justOne: true
}).
set(function(user) {
if (user) {
this.userId = user._id;
this.userType = user.constructor.modelName;
} else {
this.userId = null;
this.userType = null;
}

return user;
});

const Person = db.model('Person', personSchema);

const person = new Person({
userId: user._id,
userType: 'User'
});

await person.save();

const personFromDb = await Person.findById(person._id).populate('user');
assert.equal(personFromDb.user.name, 'Admin');
assert.equal(personFromDb.userType, 'User');
assert.equal(personFromDb.userId.toHexString(), user._id.toHexString());
});
});

0 comments on commit 9739dfc

Please sign in to comment.