Skip to content

Manually populating doesn't work for embedded discriminators in embedded array #8273

Closed
@saveman71

Description

@saveman71

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

Bug

What is the current behavior?

Manually populated as described in the docs doesn't work for discriminators.

Repro script (sorry a bit long):

// Modules
const Promise = require('bluebird');
const mongoose = require('mongoose');
mongoose.Promise = Promise;
const Schema = mongoose.Schema;

console.log(mongoose.version);

// DB
let connect = mongoose.connect('mongodb://localhost:27018/test');

// Models
const AddonSchema = new Schema({
  title: String,
});
const Addon = mongoose.model('Addon', AddonSchema);
const AddonItemSchema = new Schema({
  addon: { type: Schema.Types.ObjectId, ref: 'Addon' },
  quantity: Number,
});

const ProductSchema = new Schema({
  title: String,
});
const Product = mongoose.model('Product', ProductSchema);
const ProductItemSchema = new Schema({
  product: { type: Schema.Types.ObjectId, ref: 'Product' },
});

const OrderItemSchema = new mongoose.Schema({
  quantity: Number,
}, {discriminatorKey: '__t'});
const OrderItem = mongoose.model('OrderItem', OrderItemSchema);


const OrderSchema = new Schema({
  product: { type: Schema.Types.ObjectId, ref: 'Product' },
  noDiscriminator: {
    type: [{
      product: { type: Schema.Types.ObjectId, ref: 'Product' },
    }],
    default: [],
  },
  discriminatorNoArray: {
    type: OrderItemSchema,
  },
  items: {
    type: [OrderItemSchema],
    default: [],
  },
});

const docArray = OrderSchema.path('items');

const ProductItem = docArray
  .discriminator('ProductItem', ProductItemSchema);
const AddonItem = docArray
  .discriminator('AddonItem', AddonItemSchema);

OrderSchema.path('discriminatorNoArray').discriminator('ProductItem', ProductItemSchema);
OrderSchema.path('discriminatorNoArray').discriminator('AddonItem', AddonItemSchema);

const Order = mongoose.model('Order', OrderSchema);

// Create test data
connect.then(async () => {
  mongoose.connection.db.dropDatabase();

  const addon = await Addon({title: 'Addon title'}).save();
  const product = await Product({title: 'Product title'}).save();

  // Create order with embedded items
  const unsaved = new Order({
    product,
    noDiscriminator: [
      {
        product,
      }
    ],
    discriminatorNoArray: {
      product,
      quantity: 42,
      __t: 'ProductItem',
    },
    items: [
      {
        addon,
        quantity: 42,
        __t: 'AddonItem',
      },
      {
        product,
        quantity: 42,
        __t: 'ProductItem',
      }
    ]
  });

  // Doesn't show manually populated in items
  console.log(unsaved);

  await unsaved.save();

  // Find order, populate addon of items
  const order = await Order.findOne({}).exec();

  order.product = product;
  order.noDiscriminator[0].product = product;
  order.discriminatorNoArray.product = product;
  order.items[0].addon = addon;
  order.items[0].addon = addon;

  // Doesn't show manually populated in items
  console.log(order);
});

What are the versions of Node.js, Mongoose and MongoDB you are using?

Node.js v8.11.0
Mongoose v5.7.6

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