Skip to content

.find().populate() fails due to discriminator value not matching the model's name #8324

@ghost

Description

Do you want to request a feature or report a bug?
bug

What is the current behavior?
When using .find().populate() it fails on a virtual field.
This is caused due to the .find() being executed on a discriminated model for which the registered value is different then the ModelName.

fail:
const items = await main.find().populate('virtualField').exec();
--> items.virtualField is not correct.

success:
const items = await main.find().exec();
await main.populate('virtualField').execPopulate();
--> items.virtualField is correct.

If the current behavior is a bug, please provide the steps to reproduce.
The following (simplified code) fails with a MongooseError due to model "discriminatedValue" not being registered on the following line:
https://github.com/Automattic/mongoose/blob/master/lib/helpers/populate/getModelsMapForPopulate.js#L305

let mainSchema = new Schema(
  {
    title: { type: String },
  },
  {
    discriminatorKey: 'type',
  }
);

mainSchema.virtual('virtualField', {
  ref: 'AnotherModel',
  localField: '_id',
  foreignField: 'main',
});

let discriminatedSchema = new Schema({
  {
    description: { type: String },
  }
});

let main = connection.model('Main', mainSchema, 'main');
let discriminated = this.main.discriminator('Discriminated', discriminatedSchema, 'discriminatedValue');

const items = await main.find().populate('virtualField').exec();

The code works after changing the code to the following (where the discriminator is retrieved by going from the value to the model).

modelForFindSchema = utils.getValue(discriminatorKey, doc);
if (modelForFindSchema) {
  const discriminatorByValue = getDiscriminatorByValue(model, modelForFindSchema);
  if (discriminatorByValue !== null) {
    modelForCurrentDoc = discriminatorByValue;
  } else {
    try {
      modelForCurrentDoc = model.db.model(modelForFindSchema);
    } catch (error) {
      return error;
    }
  }
  
  ...

What is the expected behavior?
That the populate works by correctly identifying the associated model within the .find

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
Node.js: v12.11.1
MongoDB: v3.4.10
Mongoose: v5.7.9

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions