Skip to content

Commit

Permalink
refactor(discriminator): use one consolidated getConstructor() func…
Browse files Browse the repository at this point in the history
…tion to get the correct discriminator

Re: #7808
  • Loading branch information
vkarpov15 committed May 22, 2019
1 parent ec01f4f commit 4d09963
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 72 deletions.
25 changes: 25 additions & 0 deletions lib/helpers/discriminator/getConstructor.js
@@ -0,0 +1,25 @@
'use strict';

const getDiscriminatorByValue = require('../../queryhelpers').getDiscriminatorByValue;

/*!
* Find the correct constructor, taking into account discriminators
*/

module.exports = function getConstructor(Constructor, value) {
const discriminatorKey = Constructor.schema.options.discriminatorKey;
if (value != null &&
Constructor.discriminators &&
value[discriminatorKey] != null) {
if (Constructor.discriminators[value[discriminatorKey]]) {
Constructor = Constructor.discriminators[value[discriminatorKey]];
} else {
const constructorByValue = getDiscriminatorByValue(Constructor, value[discriminatorKey]);
if (constructorByValue) {
Constructor = constructorByValue;
}
}
}

return Constructor;
};
34 changes: 5 additions & 29 deletions lib/schema/documentarray.js
Expand Up @@ -11,7 +11,7 @@ const SchemaType = require('../schematype');
const discriminator = require('../helpers/model/discriminator');
const util = require('util');
const utils = require('../utils');
const getDiscriminatorByValue = require('../queryhelpers').getDiscriminatorByValue;
const getConstructor = require('../helpers/discriminator/getConstructor');

const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol;
const arrayPathSymbol = require('../helpers/symbols').arrayPathSymbol;
Expand Down Expand Up @@ -210,7 +210,7 @@ DocumentArray.prototype.doValidate = function(array, fn, scope, options) {
// If you set the array index directly, the doc might not yet be
// a full fledged mongoose subdoc, so make it into one.
if (!(doc instanceof Subdocument)) {
const Constructor = getConstructor(_this, array[i]);
const Constructor = getConstructor(_this.casterConstructor, array[i]);
doc = array[i] = new Constructor(doc, array, undefined, undefined, i);
}

Expand Down Expand Up @@ -258,7 +258,7 @@ DocumentArray.prototype.doValidateSync = function(array, scope) {
// If you set the array index directly, the doc might not yet be
// a full fledged mongoose subdoc, so make it into one.
if (!(doc instanceof Subdocument)) {
const Constructor = getConstructor(this, array[i]);
const Constructor = getConstructor(this.casterConstructor, array[i]);
doc = array[i] = new Constructor(doc, array, undefined, undefined, i);
}

Expand Down Expand Up @@ -297,7 +297,7 @@ DocumentArray.prototype.getDefault = function(scope) {
ret[arrayParentSymbol] = null;

for (let i = 0; i < ret.length; ++i) {
const Constructor = getConstructor(this, ret[i]);
const Constructor = getConstructor(this.casterConstructor, ret[i]);
ret[i] = new Constructor(ret[i], ret, undefined,
undefined, i);
}
Expand Down Expand Up @@ -353,7 +353,7 @@ DocumentArray.prototype.cast = function(value, doc, init, prev, options) {
continue;
}

const Constructor = getConstructor(this, value[i]);
const Constructor = getConstructor(this.casterConstructor, value[i]);

// Check if the document has a different schema (re gh-3701)
if ((value[i].$__) &&
Expand Down Expand Up @@ -410,30 +410,6 @@ DocumentArray.prototype.cast = function(value, doc, init, prev, options) {
return value;
};

/*!
* Find the correct subdoc constructor, taking into account discriminators
*/

function getConstructor(docArray, subdoc) {
let Constructor = docArray.casterConstructor;
const schema = Constructor.schema;
const discriminatorKey = schema.options.discriminatorKey;
const discriminatorValue = subdoc[discriminatorKey];
if (Constructor.discriminators && discriminatorValue != null) {
if (Constructor.discriminators[discriminatorValue]) {
Constructor = Constructor.discriminators[discriminatorValue];
} else {
const constructorByValue = getDiscriminatorByValue(Constructor,
discriminatorValue);
if (constructorByValue) {
Constructor = constructorByValue;
}
}
}

return Constructor;
}

/*!
* ignore
*/
Expand Down
47 changes: 4 additions & 43 deletions lib/schema/embedded.js
Expand Up @@ -13,7 +13,7 @@ const castToNumber = require('./operators/helpers').castToNumber;
const discriminator = require('../helpers/model/discriminator');
const geospatial = require('./operators/geospatial');
const get = require('../helpers/get');
const getDiscriminatorByValue = require('../queryhelpers').getDiscriminatorByValue;
const getConstructor = require('../helpers/discriminator/getConstructor');
const internalToObjectOptions = require('../options').internalToObjectOptions;

let Subdocument;
Expand Down Expand Up @@ -149,20 +149,7 @@ Embedded.prototype.cast = function(val, doc, init, priorVal) {
throw new ObjectExpectedError(this.path, val);
}

let Constructor = this.caster;
const discriminatorKey = Constructor.schema.options.discriminatorKey;
if (val != null &&
Constructor.discriminators &&
val[discriminatorKey] != null) {
if (Constructor.discriminators[val[discriminatorKey]]) {
Constructor = Constructor.discriminators[val[discriminatorKey]];
} else {
const constructorByValue = getDiscriminatorByValue(Constructor, val[discriminatorKey]);
if (constructorByValue) {
Constructor = constructorByValue;
}
}
}
const Constructor = getConstructor(this.caster, val);

let subdoc;

Expand Down Expand Up @@ -216,20 +203,7 @@ Embedded.prototype.castForQuery = function($conditional, val) {
val = this._applySetters(val);
}

let Constructor = this.caster;
const discriminatorKey = Constructor.schema.options.discriminatorKey;
if (val != null &&
Constructor.discriminators &&
val[discriminatorKey] != null) {
if (Constructor.discriminators[val[discriminatorKey]]) {
Constructor = Constructor.discriminators[val[discriminatorKey]];
} else {
const constructorByValue = getDiscriminatorByValue(Constructor, val[discriminatorKey]);
if (constructorByValue) {
Constructor = constructorByValue;
}
}
}
const Constructor = getConstructor(this.caster, val);

try {
val = new Constructor(val);
Expand All @@ -250,20 +224,7 @@ Embedded.prototype.castForQuery = function($conditional, val) {
*/

Embedded.prototype.doValidate = function(value, fn, scope, options) {
let Constructor = this.caster;
const discriminatorKey = Constructor.schema.options.discriminatorKey;
if (value != null &&
Constructor.discriminators &&
value[discriminatorKey] != null) {
if (Constructor.discriminators[value[discriminatorKey]]) {
Constructor = Constructor.discriminators[value[discriminatorKey]];
} else {
const constructorByValue = getDiscriminatorByValue(Constructor, value[discriminatorKey]);
if (constructorByValue) {
Constructor = constructorByValue;
}
}
}
const Constructor = getConstructor(this.caster, value);

if (options && options.skipSchemaValidators) {
if (!(value instanceof Constructor)) {
Expand Down

0 comments on commit 4d09963

Please sign in to comment.