Skip to content

Allow discriminator models to add new statics #15556

@domharrington

Description

@domharrington

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the feature has not already been requested

🚀 Feature Proposal

When you try and add another static to a discriminated model, you get a runtime error:

/private/tmp/mongoose-discriminator-statics/node_modules/mongoose/lib/helpers/model/discriminator.js:215
          throw new Error('Can\'t customize discriminator option ' + _key +
                ^

Error: Can't customize discriminator option statics (can only modify toJSON, toObject, _id, id, virtuals, methods)
    at merge (/private/tmp/mongoose-discriminator-statics/node_modules/mongoose/lib/helpers/model/discriminator.js:215:17)
    at discriminator (/private/tmp/mongoose-discriminator-statics/node_modules/mongoose/lib/helpers/model/discriminator.js:244:3)
    at Model.discriminator (/private/tmp/mongoose-discriminator-statics/node_modules/mongoose/lib/model.js:973:12)
    at mongoose (/private/tmp/mongoose-discriminator-statics/index2.ts:21:32)
    at Object.<anonymous> (/private/tmp/mongoose-discriminator-statics/index2.ts:24:34)
    at Module._compile (node:internal/modules/cjs/loader:1529:14)
    at Object.transformer (/Users/domh/.npm/_npx/fd45a72a545557e9/node_modules/tsx/dist/register-D46fvsV_.cjs:3:1104)
    at Module.load (node:internal/modules/cjs/loader:1275:32)
    at Module._load (node:internal/modules/cjs/loader:1096:12)
    at cjsLoader (node:internal/modules/esm/translators:298:15)

Motivation

You may want to define different statics on the base model and discriminated model. I would expect any statics defined on the child model to be merged with the parent model, unless the keys match then I would expect it to overwrite the parent model.

I tried to find the rationale behind this decision but couldn't find it.

Example

This code errors with "Error: Can't customize discriminator option statics (can only modify toJSON, toObject, _id, id, virtuals, methods)"

import mongoose from 'mongoose';

const eventSchema = new mongoose.Schema({ time: Date }, {
  discriminatorKey: 'kind',
  statics: {
    findEvents(filter: any) {
      return this.find(filter);
    },
  },
});
const Event = mongoose.model('Event', eventSchema);

const clickedEventSchema = new mongoose.Schema({ url: String }, {
  discriminatorKey: 'kind',
  statics: {
    findClickedEvents(filter: any) {
      return this.find(filter);
    },
  },
});
const ClickedLinkEvent = Event.discriminator('ClickedLink', clickedEventSchema);

const clickedEvent = new ClickedLinkEvent({ url: 'https://www.google.com' });
clickedEvent.findClickedEvents({})
            // ^? any

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementThis issue is a user-facing general improvement that doesn't fix a bug or add a new featurenew featureThis change adds new functionality, like a new method or class

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions