diff --git a/lib/schema.js b/lib/schema.js index 2ed2bd3c97f..2a1867cd824 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -2217,7 +2217,7 @@ Schema.prototype.virtual = function(name, options) { } // Workaround for gh-8198: if virtual is under document array, make a fake - // virtual. See gh-8210 + // virtual. See gh-8210, gh-13189 const parts = name.split('.'); let cur = parts[0]; for (let i = 0; i < parts.length - 1; ++i) { diff --git a/test/model.populate.test.js b/test/model.populate.test.js index 3e6cbf79848..b4b4adbd213 100644 --- a/test/model.populate.test.js +++ b/test/model.populate.test.js @@ -7934,13 +7934,19 @@ describe('model: populate:', function() { assert.equal(res.nested.events[0].nestedLayer.users_$[0].name, 'test'); }); - it('accessing populate virtual prop (gh-8198)', async function() { + it('accessing populate virtual prop (gh-13189) (gh-8198)', async function() { const FooSchema = new Schema({ name: String, children: [{ barId: { type: Schema.Types.ObjectId, ref: 'Test' }, quantity: Number - }] + }], + child: { + barId: { + type: 'ObjectId', + ref: 'Test' + } + } }); FooSchema.virtual('children.bar', { ref: 'Test', @@ -7948,6 +7954,12 @@ describe('model: populate:', function() { foreignField: '_id', justOne: true }); + FooSchema.virtual('child.bar', { + ref: 'Test', + localField: 'child.barId', + foreignField: '_id', + justOne: true + }); const BarSchema = Schema({ name: String }); const Foo = db.model('Test1', FooSchema); const Bar = db.model('Test', BarSchema); @@ -7955,10 +7967,18 @@ describe('model: populate:', function() { const bar = await Bar.create({ name: 'bar' }); const foo = await Foo.create({ name: 'foo', - children: [{ barId: bar._id, quantity: 1 }] + children: [{ barId: bar._id, quantity: 1 }], + child: { + barId: bar._id + } }); - const foo2 = await Foo.findById(foo._id).populate('children.bar'); + const foo2 = await Foo.findById(foo._id).populate('children.bar child.bar'); assert.equal(foo2.children[0].bar.name, 'bar'); + assert.equal(foo2.child.bar.name, 'bar'); + + const asObject = foo2.toObject({ virtuals: true }); + assert.equal(asObject.children[0].bar.name, 'bar'); + assert.equal(asObject.child.bar.name, 'bar'); }); describe('gh-8247', function() {