Automattic / Automattic/mongoose
Decouple discriminators from Models
- Dominant language
- JavaScript
- Stars
- 27.5k
- Forks
- 4k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 32
Description
**Do you want to request a *feature* or report a *bug*?**
Feature Request
**What is the current behavior?**
- Discriminators operate on the Model of the discriminated Schema.
- Anything that operates on Schemas (e.g. browser validation) always operates on incomplete Schemas, due to the Schema having none of the properties of the Schema it will be discriminating. A discriminating Schema isn't *actually* inheriting anything, the Model is. A discriminating Schema isn't usable, only it's Model is.
**What is the expected behavior?**
Discriminators being a method of Schema inheritance, not Model inheritance. Possibly via es6 class inheritance or through the options.
> Discriminators are a schema inheritance mechanism. They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB collection. [documentation](http://mongoosejs.com/docs/discriminators.html#the-model-discriminator-function)
A Schema's job is to [define the shape of the documents within that collection](http://mongoosejs.com/docs/guide.html#definition). A discriminator's Schema, currently, doesn't fit that role. It describes the shape of the difference. If Schemas are meant to decouple the document shape from the Model, then Discriminators don't have this.
Potential Drawbacks:
- A Schema couldn't be used to discriminate multiple Schemas, due to it being tied to a specific inherited Schema. I'm not sure how common this use case is.
- How Models of discriminating Schemas are currently made would change. They're currently made from the Model they discriminate from, but they would have to get that information through the Schemas. (ie, the Discriminating Model would look in it's Schema, looking in it's inherited Schema, find it's Model, and that's the MongoDB collection to use).
I came across this working on [mongoose-normalizr](https://github.com/saiichihashimoto/mongoose-normalizr), which generates [normalizr](https://github.com/paularmstrong/normalizr) Entities using mongoose Schemas. This allows you to define the relationships between resources once (in mongoose schemas) and still be able to normalize & denormalize them via normalizr, most commonly in a browser (probably into a redux/flux store). Discriminators currently *can't* be supported, since they only exist in Models. A workaround would be to pass in which Schemas discriminate which Schemas in a separate mapping. The motivation behind mongoose-normalizr is to reduce [repeating the relationship definitions](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) so this doesn't make sense.
Since this is an overhaul of discriminators, perhaps it isn't possible. In that case, I think Discriminators need to be redefined as *Model* inheritance and *Schema* inheritance would be put in place. This could have the interesting side effect that Schema inheritance doesn't necessarily have to be in the same underlying MongoDB collection. Two different models could have the same underlying collection, as long as the Schemas inherit each other. But they could also be used entirely separately, albeit having a very similar document shape.
Contributor guide
Research direction
No implementation files or tests are named. Start by reading the discriminators documentation and tracing how discriminator Schemas and Models are currently connected; compare that behavior with the Schema inheritance and Model inheritance alternatives described here. Done would require a decided design and corresponding implementation, documentation, and tests for discriminator behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, mongodb
- Domain
- backend, database
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100