diff --git a/lib/helpers/discriminator/mergeDiscriminatorSchema.js b/lib/helpers/discriminator/mergeDiscriminatorSchema.js index fcba6c231c4..b48d5c4db07 100644 --- a/lib/helpers/discriminator/mergeDiscriminatorSchema.js +++ b/lib/helpers/discriminator/mergeDiscriminatorSchema.js @@ -34,7 +34,8 @@ module.exports = function mergeDiscriminatorSchema(to, from, path, seen) { key === 'base' || key === '_applyDiscriminators' || key === '_userProvidedOptions' || - key === 'options') { + key === 'options' || + key === 'tree') { continue; } } @@ -73,4 +74,8 @@ module.exports = function mergeDiscriminatorSchema(to, from, path, seen) { mergeDiscriminatorSchema(to[key], from[key], path ? path + '.' + key : key, seen); } } + + if (from != null && from.instanceOfSchema) { + to.tree = Object.assign({}, from.tree, to.tree); + } }; diff --git a/test/model.discriminator.test.js b/test/model.discriminator.test.js index 6f7fd05d4a2..400cf976f63 100644 --- a/test/model.discriminator.test.js +++ b/test/model.discriminator.test.js @@ -2180,4 +2180,27 @@ describe('model', function() { assert.ok(innerBuildingsPath.schemaOptions.type.discriminators.Garage); assert.equal(innerBuildingsPath.schemaOptions.type.discriminators.Garage.discriminatorMapping.value, 'G'); }); + + it('runs base schema paths validators and setters before child schema validators and setters (gh-13794)', async function() { + const baseSchema = new Schema({ + f1: { + type: Number, + set() { + return 1; + } + } + }); + const childSchema = new Schema({ + f2: { + type: Number, + set() { + return this.f1; + } + } + }); + const Test = db.model('Test', baseSchema); + const Child = Test.discriminator('Child', childSchema); + const doc = new Child({ f1: 2, f2: 2 }); + assert.strictEqual(doc.f2, 1); + }); });