diff --git a/lib/helpers/discriminator/getConstructor.js b/lib/helpers/discriminator/getConstructor.js index e5a12950fef..04a3dedd83a 100644 --- a/lib/helpers/discriminator/getConstructor.js +++ b/lib/helpers/discriminator/getConstructor.js @@ -1,6 +1,6 @@ 'use strict'; -const getDiscriminatorByValue = require('../../queryhelpers').getDiscriminatorByValue; +const getDiscriminatorByValue = require('./getDiscriminatorByValue'); /*! * Find the correct constructor, taking into account discriminators diff --git a/lib/helpers/discriminator/getDiscriminatorByValue.js b/lib/helpers/discriminator/getDiscriminatorByValue.js new file mode 100644 index 00000000000..334be1500d2 --- /dev/null +++ b/lib/helpers/discriminator/getDiscriminatorByValue.js @@ -0,0 +1,27 @@ +'use strict'; + +/*! +* returns discriminator by discriminatorMapping.value +* +* @param {Model} model +* @param {string} value +*/ + +module.exports = function getDiscriminatorByValue(model, value) { + let discriminator = null; + if (!model.discriminators) { + return discriminator; + } + for (const name in model.discriminators) { + const it = model.discriminators[name]; + if ( + it.schema && + it.schema.discriminatorMapping && + it.schema.discriminatorMapping.value == value + ) { + discriminator = it; + break; + } + } + return discriminator; +} \ No newline at end of file diff --git a/lib/helpers/populate/getModelsMapForPopulate.js b/lib/helpers/populate/getModelsMapForPopulate.js index 990f8a64c32..d2c3e449672 100644 --- a/lib/helpers/populate/getModelsMapForPopulate.js +++ b/lib/helpers/populate/getModelsMapForPopulate.js @@ -2,6 +2,7 @@ const MongooseError = require('../../error/index'); const get = require('../get'); +const getDiscriminatorByValue = require('../discriminator/getDiscriminatorByValue'); const isPathExcluded = require('../projection/isPathExcluded'); const getSchemaTypes = require('./getSchemaTypes'); const getVirtual = require('./getVirtual'); @@ -297,12 +298,18 @@ module.exports = function getModelsMapForPopulate(model, docs, options) { if (!schema && discriminatorKey) { modelForFindSchema = utils.getValue(discriminatorKey, doc); - if (modelForFindSchema) { - try { - modelForCurrentDoc = model.db.model(modelForFindSchema); - } catch (error) { - return error; + // `modelForFindSchema` is the discriminator value, so we might need + // find the discriminated model name + const discriminatorModel = getDiscriminatorByValue(model, modelForFindSchema); + if (discriminatorModel != null) { + modelForCurrentDoc = discriminatorModel; + } else { + try { + modelForCurrentDoc = model.db.model(modelForFindSchema); + } catch (error) { + return error; + } } schemaForCurrentDoc = modelForCurrentDoc.schema._getSchema(options.path); diff --git a/lib/model.js b/lib/model.js index ba982da837d..a48cecb3b27 100644 --- a/lib/model.js +++ b/lib/model.js @@ -30,7 +30,7 @@ const assignVals = require('./helpers/populate/assignVals'); const castBulkWrite = require('./helpers/model/castBulkWrite'); const discriminator = require('./helpers/model/discriminator'); const each = require('./helpers/each'); -const getDiscriminatorByValue = require('./queryhelpers').getDiscriminatorByValue; +const getDiscriminatorByValue = require('./helpers/discriminator/getDiscriminatorByValue'); const getModelsMapForPopulate = require('./helpers/populate/getModelsMapForPopulate'); const immediate = require('./helpers/immediate'); const internalToObjectOptions = require('./options').internalToObjectOptions; diff --git a/lib/query.js b/lib/query.js index 4a31e40d50f..bb501e5c5ae 100644 --- a/lib/query.js +++ b/lib/query.js @@ -18,6 +18,7 @@ const castArrayFilters = require('./helpers/update/castArrayFilters'); const castUpdate = require('./helpers/query/castUpdate'); const completeMany = require('./helpers/query/completeMany'); const get = require('./helpers/get'); +const getDiscriminatorByValue = require('./helpers/discriminator/getDiscriminatorByValue'); const hasDollarKeys = require('./helpers/query/hasDollarKeys'); const helpers = require('./queryhelpers'); const isInclusive = require('./helpers/projection/isInclusive'); @@ -4429,7 +4430,7 @@ Query.prototype._castUpdate = function _castUpdate(obj, overwrite) { typeof filter[schema.options.discriminatorKey] !== 'object' && schema.discriminators != null) { const discriminatorValue = filter[schema.options.discriminatorKey]; - const byValue = helpers.getDiscriminatorByValue(this.model, discriminatorValue); + const byValue = getDiscriminatorByValue(this.model, discriminatorValue); schema = schema.discriminators[discriminatorValue] || (byValue && byValue.schema) || schema; diff --git a/lib/queryhelpers.js b/lib/queryhelpers.js index 045354f0f84..fc1a5953093 100644 --- a/lib/queryhelpers.js +++ b/lib/queryhelpers.js @@ -7,6 +7,8 @@ const checkEmbeddedDiscriminatorKeyProjection = require('./helpers/discriminator/checkEmbeddedDiscriminatorKeyProjection'); const get = require('./helpers/get'); +const getDiscriminatorByValue = + require('./helpers/discriminator/getDiscriminatorByValue'); const isDefiningProjection = require('./helpers/projection/isDefiningProjection'); const utils = require('./utils'); @@ -71,34 +73,6 @@ exports.preparePopulationOptionsMQ = function preparePopulationOptionsMQ(query, return pop; }; - -/*! - * returns discriminator by discriminatorMapping.value - * - * @param {Model} model - * @param {string} value - */ -function getDiscriminatorByValue(model, value) { - let discriminator = null; - if (!model.discriminators) { - return discriminator; - } - for (const name in model.discriminators) { - const it = model.discriminators[name]; - if ( - it.schema && - it.schema.discriminatorMapping && - it.schema.discriminatorMapping.value == value - ) { - discriminator = it; - break; - } - } - return discriminator; -} - -exports.getDiscriminatorByValue = getDiscriminatorByValue; - /*! * If the document is a mapped discriminator type, it returns a model instance for that type, otherwise, * it returns an instance of the given model. diff --git a/lib/schema/array.js b/lib/schema/array.js index 09547385374..ba1e5d475b7 100644 --- a/lib/schema/array.js +++ b/lib/schema/array.js @@ -17,7 +17,7 @@ const util = require('util'); const utils = require('../utils'); const castToNumber = require('./operators/helpers').castToNumber; const geospatial = require('./operators/geospatial'); -const getDiscriminatorByValue = require('../queryhelpers').getDiscriminatorByValue; +const getDiscriminatorByValue = require('../helpers/discriminator/getDiscriminatorByValue'); let MongooseArray; let EmbeddedDoc; diff --git a/lib/types/documentarray.js b/lib/types/documentarray.js index 87757e4f171..8ffa7674a31 100644 --- a/lib/types/documentarray.js +++ b/lib/types/documentarray.js @@ -8,7 +8,7 @@ const CoreMongooseArray = require('./core_array'); const Document = require('../document'); const ObjectId = require('./objectid'); const castObjectId = require('../cast/objectid'); -const getDiscriminatorByValue = require('../queryhelpers').getDiscriminatorByValue; +const getDiscriminatorByValue = require('../helpers/discriminator/getDiscriminatorByValue'); const internalToObjectOptions = require('../options').internalToObjectOptions; const util = require('util'); const utils = require('../utils'); diff --git a/test/model.populate.test.js b/test/model.populate.test.js index adc08ac92a2..f673dfff1b4 100644 --- a/test/model.populate.test.js +++ b/test/model.populate.test.js @@ -8825,7 +8825,6 @@ describe('model: populate:', function() { yield Model.create({ main: d._id }); const docs = yield Main.find().populate('virtualField').exec(); - console.log(docs.map(d => d.virtualField)) assert.ok(docs[0].virtualField[0].main); }); });