[Proposal] Reconsidering validator contexts and calling behavior
See original GitHub issueWhen updating a property of a sub doc, like so:
doc.sub.property = "value"
doc.save()
Its validators are called twice, once in the context of the main doc and once in the context of the sub doc. This is probably intended behavior, however I would really consider thinking about this.
I encountered this “feature” because I needed to access a property’s siblings in its validator function (f.i. to check whether a date is before another stored in the database). The current behavior makes the validator never pass, because depending on what context (this
) you rely on, the following is thrown for the other context: Cannot read property x of undefined
.
Now, I know I can easily work around this by normalizing what I receive, something along the lines of:
let sub = this.sub || this
But this is just a hack, I think we face a more fundamental problem because Mongoose passes varying contexts to validators (and possibly more functions that operate on properties, like required
, set
…).
I think we should always start from the smallest document instance, because, while providing the parent (more possibly useful data) seems tempting, using the sub doc as a standalone would create varying contexts once again. (However I’m not sure whether that should be allowed anyway, but that’s topic for another discussion :p.) We could enhance the context if we have more data to provide.
What if validators (and other functions) would receive something like below as value for this
?
{
document: {
// properties of sub doc
sample: "test"
// ...
},
parent: {
// properties of parent
subdoc: {
sample: "test"
}
// ...
}
}
Note I chose for an extra layer to prevent naming conflicts with document properties, and allow for extensibility. (Monoose could hook extra properties and methods to this
, that validators could use…) When used as a standalone, parent will not be present obviously. document
should still be present though, to ensure we always provide the same context upon which we can rely then.
This would go behind an option (f.i. richContext
) of course, to ensure backwards compatibility.
However, validators are still being called twice in some scenarios, which is redundant and inefficient. I think we should address that too. The validation should only be called on the sub doc level, in line with the reasoning above.
Let me know what you think 😃
I’m using Mongoose 4.9.7 as of writing.
Issue Analytics
- State:
- Created 6 years ago
- Comments:7 (3 by maintainers)
yeah i think this is an issue too, and it certainly feels like a hack to do something like:
i think this is a repro script that captures the problem:
I wonder if running the validators only once would be considered a breaking backwards change though so only fit for a major release? I’m of the opinion that it’s not backwards breaking, but open to discussion
This looks fixed in Mongoose 6. Running the following script:
shows that the value of
this
in the validator is in fact the subdocument. I’ll close this issue for now. Please re-open if this is still an issue.