Skip to content

Commit

Permalink
Merge pull request #12613 from lpizzinidev/feat-applyplugins
Browse files Browse the repository at this point in the history
feat(model): add `mergePlugins` option to `discriminator`
  • Loading branch information
vkarpov15 authored Nov 4, 2022
2 parents ae14d0e + edca782 commit 5a40613
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 4 deletions.
5 changes: 3 additions & 2 deletions lib/helpers/model/discriminator.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,9 @@ module.exports = function discriminator(model, name, schema, tiedValue, applyPlu
if (mergeHooks) {
schema.s.hooks = model.schema.s.hooks.merge(schema.s.hooks);
}

schema.plugins = Array.prototype.slice.call(baseSchema.plugins);
if (applyPlugins) {
schema.plugins = Array.prototype.slice.call(baseSchema.plugins);
}
schema.callQueue = baseSchema.callQueue.concat(schema.callQueue);
delete schema._requiredpaths; // reset just in case Schema#requiredPaths() was called on either schema
}
Expand Down
4 changes: 3 additions & 1 deletion lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,7 @@ Model.exists = function exists(filter, options, callback) {
* @param {Boolean} [options.clone=true] By default, `discriminator()` clones the given `schema`. Set to `false` to skip cloning.
* @param {Boolean} [options.overwriteModels=false] by default, Mongoose does not allow you to define a discriminator with the same name as another discriminator. Set this to allow overwriting discriminators with the same name.
* @param {Boolean} [options.mergeHooks=true] By default, Mongoose merges the base schema's hooks with the discriminator schema's hooks. Set this option to `false` to make Mongoose use the discriminator schema's hooks instead.
* @param {Boolean} [options.mergePlugins=true] By default, Mongoose merges the base schema's plugins with the discriminator schema's plugins. Set this option to `false` to make Mongoose use the discriminator schema's plugins instead.
* @return {Model} The newly created discriminator model
* @api public
*/
Expand All @@ -1232,6 +1233,7 @@ Model.discriminator = function(name, schema, options) {
options = options || {};
const value = utils.isPOJO(options) ? options.value : options;
const clone = typeof options.clone === 'boolean' ? options.clone : true;
const mergePlugins = typeof options.mergePlugins === 'boolean' ? options.mergePlugins : true;

_checkContext(this, 'discriminator');

Expand All @@ -1242,7 +1244,7 @@ Model.discriminator = function(name, schema, options) {
schema = schema.clone();
}

schema = discriminator(this, name, schema, value, true, options.mergeHooks);
schema = discriminator(this, name, schema, value, mergePlugins, options.mergeHooks);
if (this.db.models[name] && !schema.options.overwriteModels) {
throw new OverwriteModelError(name);
}
Expand Down
38 changes: 38 additions & 0 deletions test/model.discriminator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2039,4 +2039,42 @@ describe('model', function() {
schema.pre('save', function testHook12472() {});
}
});

it('supports `mergePlugins` option to use the discriminator schema\'s plugins over the base schema\'s (gh-12604)', function() {
let pluginTimes = 0;
const shapeDef = { name: String };
const shapeSchema = Schema(shapeDef, { discriminatorKey: 'kind' });
shapeSchema.plugin(myPlugin, { opts1: true });

const Shape = db.model('Test', shapeSchema);

const triangleSchema = Schema({ ...shapeDef, sides: { type: Number, enum: [3] } });
triangleSchema.plugin(myPlugin, { opts2: true });
const Triangle = Shape.discriminator(
'Triangle',
triangleSchema
);

const squareSchema = Schema({ ...shapeDef, sides: { type: Number, enum: [4] } });
squareSchema.plugin(myPlugin, { opts3: true });
const Square = Shape.discriminator(
'Square',
squareSchema,
{ mergeHooks: false, mergePlugins: false }
);

assert.equal(Triangle.schema.s.hooks._pres.get('save').filter(hook => hook.fn.name === 'testHook12604').length, 2);
assert.equal(Square.schema.s.hooks._pres.get('save').filter(hook => hook.fn.name === 'testHook12604').length, 1);

const squareFilteredPlugins = Square.schema.plugins.filter((obj) => obj.fn.name === 'myPlugin');
assert.equal(squareFilteredPlugins.length, 1);
assert.equal(squareFilteredPlugins[0].opts['opts3'], true);

assert.equal(pluginTimes, 3);

function myPlugin(schema) {
pluginTimes += 1;
schema.pre('save', function testHook12604() {});
}
});
});
2 changes: 1 addition & 1 deletion test/types/discriminator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ doc.email = 'hello';
const Disc2 = Base.discriminator<IDiscriminatorTest>(
'Disc2',
new Schema({ email: { type: String } }),
{ value: 'test', mergeHooks: false }
{ value: 'test', mergeHooks: false, mergePlugins: false }
);

function test(): void {
Expand Down
1 change: 1 addition & 0 deletions types/models.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ declare module 'mongoose' {
clone?: boolean;
overwriteModels?: boolean;
mergeHooks?: boolean;
mergePlugins?: boolean;
}

export interface AcceptsDiscriminator {
Expand Down

0 comments on commit 5a40613

Please sign in to comment.