Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded discriminators with "tiedValue" dont populate without explicitly specifing "model" #10231

Closed
hasezoey opened this issue May 11, 2021 · 5 comments
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@hasezoey
Copy link
Collaborator

hasezoey commented May 11, 2021

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

What is the current behavior?
When using Embedded discriminators with tiedValue instead of just name it doesn't populate without also specifying model on populate call

If the current behavior is a bug, please provide the steps to reproduce.

// NodeJS: 16.1.0
// MongoDB: 4.2-bionic (Docker)
import * as mongoose from "mongoose"; // mongoose@5.12.7
import { inspect } from "util";
import { schemas } from "@typegoose/typegoose/lib/internal/data";

enum ActivityKind {
  Talk = "TALK",
  None = "NONE"
}

const GuestSchema = new mongoose.Schema({
  dummy: String
});

const ActivitySchema = new mongoose.Schema({
  title: String,
  kind: { required: true, type: String, enum: [ActivityKind.Talk] }
}, { discriminatorKey: "kind" });

const ActivityTalkSchema = new mongoose.Schema({
  speakers: [{ type: mongoose.Schema.Types.ObjectId, ref: "Guest" }]
});
ActivityTalkSchema.add(ActivitySchema);
// skip check because otherwise "add" can not be used
(ActivityTalkSchema.paths.kind as any).options.$skipDiscriminatorCheck = true;

const SponsorSchema = new mongoose.Schema({
  speakers: [{ type: mongoose.Schema.Types.ObjectId, ref: "Guest" }]
});

const ProgrammeSchema = new mongoose.Schema({
  sponsors: [SponsorSchema],
  activities: [{
    required: true,
    type: ActivitySchema
  }]
});
// @ts-expect-error mongoose does not have typings for "discriminator" without casting beforehand to DocumentArray
ProgrammeSchema.path("activities").discriminator("ActivityTalk", ActivityTalkSchema, ActivityKind.Talk);

const GuestModel = mongoose.model("Guest", GuestSchema);
const ProgrammeModel = mongoose.model("Programme", ProgrammeSchema);

(async () => {
  console.log(inspect(schemas.get("Activity"), false, 5));
  await mongoose.connect(`mongodb://localhost:27017/`, { useNewUrlParser: true, dbName: "verifyMASTER", useCreateIndex: true, useUnifiedTopology: true });

  // seed the database
  const guest1 = await GuestModel.create({ dummy: "1" });
  const guest2 = await GuestModel.create({ dummy: "2" });

  const programme1 = await ProgrammeModel.create({
    sponsors: [
      { speakers: [guest1, guest2] }
    ],
    activities: [
      { title: "hello", kind: ActivityKind.Talk, speakers: [guest1, guest2] }
    ]
  });

  const event = await ProgrammeModel.findOne({ _id: programme1._id }).orFail().exec();
  console.log("found", inspect(event, false, 5, true));
  await event.populate({ path: "activities.speakers" }).execPopulate();

  console.log("populate", inspect(event, false, 5, true));

  await mongoose.disconnect();
})();
{
    "compileOnSave": true,
    "typeAcquisition": {
        "enable": true
    },
    "compilerOptions": {
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "declarationMap": true,
        "outDir": "lib",
        "moduleResolution": "node",
        "target": "es6",
        "module": "commonjs",
        "newLine": "LF",
        "sourceMap": true,
        "removeComments": true,
        "strict": true,
        "allowUnreachableCode": false,
        "pretty": true,
        "declaration": true,
        "incremental": true,
        "tsBuildInfoFile": ".tsbuildinfo",
        "lib": [
            "esnext"
        ]
    },
    "include": [
        "src/**/*"
    ]
}

What is the expected behavior?
to populate without also specifying model

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
nodejs: 16.1.0
mongoose: 5.12.7
typescript: 4.2.4

PS: documentation taken from here

Note: populate work when not using tiedValue

PPS: if needed, there is also an reproduction repository with this code: https://github.com/typegoose/typegoose-testing/tree/verify537

@hasezoey
Copy link
Collaborator Author

just wanna add:
this example is made with typescript, but should not be necessary to reproduce this issue - it is just for convenience

@IslandRhythms IslandRhythms added the needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity label May 12, 2021
@IslandRhythms
Copy link
Collaborator

const mongoose = require('mongoose');
const util = require('util');
const {inspect} = util;
const {Schema} = mongoose;

const GuestSchema = new Schema ({
    dummy: String
});

const ActivitySchema = new Schema({
    title: String,
    kind: {required: true, type: String, enum: ["TALK"]}}, 
    {discriminatorKey: "kind"})

const ActivityTalkSchema = new Schema({
    speakers: [{type: mongoose.Schema.Types.ObjectId, ref: "Guest"}]
});

ActivityTalkSchema.add(ActivitySchema);

ActivityTalkSchema.paths.kind.options.$skipDiscriminatorCheck = true;

const SponsorSchema = new Schema({
    speakers: [{type: mongoose.Schema.Types.ObjectId, ref: "Guest"}]
});

const ProgrammeSchema = new Schema({
    sponsors: [SponsorSchema],
    activities: [{required: true, type: ActivitySchema}]
});

ProgrammeSchema.path("activities").discriminator("ActivityTalk", ActivityTalkSchema, "TALK");

const GuestModel = mongoose.model("Guest", GuestSchema);
const ProgrammeModel = mongoose.model("Programmer", ProgrammeSchema);

async function test() {
await mongoose.connect('mongodb://localhost:27017/', {
    useNewUrlParser: true,
    useCreateIndex: true,
    useUnifiedTopology: true
});

const guest1 = await GuestModel.create({dummy: "1"})
const guest2 = await GuestModel.create({dummy: "2"});

const programme1 = await ProgrammeModel.create({sponsors: [
    {speakers: [guest1, guest2]}
],
activities: [
    {title: "hello", kind: "TALK"}
]});

const event = await ProgrammeModel.findOne({_id: programme1._id}).orFail().exec();
console.log("found", inspect(event, false, 5, true));
await event.populate({path: "activities.speakers"}).execPopulate();
console.log("populate", inspect(event, false, 5, true));
await mongoose.disconnect();
}

test();

Output:

found {
  _id: 609c39bef31ef11ddcead82f,
  sponsors: [
    {
      speakers: [ 609c39bef31ef11ddcead82d, 609c39bef31ef11ddcead82e ],
      _id: 609c39bef31ef11ddcead830
    }
  ],
  activities: [
    {
      speakers: [],
      kind: 'TALK',
      _id: 609c39bef31ef11ddcead831,
      title: 'hello'
    }
  ],
  __v: 0
}
populate {
  _id: 609c39bef31ef11ddcead82f,
  sponsors: [
    {
      speakers: [ 609c39bef31ef11ddcead82d, 609c39bef31ef11ddcead82e ],
      _id: 609c39bef31ef11ddcead830
    }
  ],
  activities: [
    {
      speakers: [],
      kind: 'TALK',
      _id: 609c39bef31ef11ddcead831,
      title: 'hello'
    }
  ],
  __v: 0
}

@hasezoey
Copy link
Collaborator Author

@IslandRhythms what exactly "needs clarification"?

@IslandRhythms IslandRhythms added has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed needs clarification This issue doesn't have enough information to be actionable. Close after 14 days of inactivity has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels May 17, 2021
@vkarpov15 vkarpov15 added this to the 5.12.10 milestone May 18, 2021
@vkarpov15
Copy link
Collaborator

@hasezoey "needs clarification" means we don't think we have enough info to reasonably try to repro this issue.

@hasezoey
Copy link
Collaborator Author

@vkarpov15 i basically know what i means, i just asked what was needed aside from the information already given (i mean versions are there, problem is stated and reproduction script is also provided (and confirmed to reproduce at the time?))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. typescript Types or Types-test related issue / Pull Request
Projects
None yet
Development

No branches or pull requests

3 participants