Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make doValidate() on document array elements run validation on the whole subdoc #11902

Merged
merged 3 commits into from
Jun 13, 2022

Conversation

vkarpov15
Copy link
Collaborator

Fix #11770

Summary

In #11770 I made a note that we leave subdocuments in init state after save() to work around some issues like #6818. That is technically incorrect, because init should only be used for paths that are loaded from the database. The underlying issue comes down to the fact that array subdocument paths' doValidate() function doesn't run validation on paths in the document.

In this PR, I made it so that the embedded schema type in document arrays have a doValidate() that is the same as SubdocumentPath's. In order to support this change, needed to fix a couple of places where we relied on the old behavior in update validators and Model.validate().

Future work: make array subdocument paths a separate class, and make primitive arrays also validate all their subpaths when calling doValidate().

We should probably put this change in 6.4, or hold off until after 6.4 It is a fairly sizable change of Mongoose internals, and while our tests do all pass, I'd like to be cautious with this one.

Examples

@vkarpov15 vkarpov15 self-assigned this Jun 6, 2022
lib/document.js Outdated
@@ -2505,6 +2505,14 @@ function _getPathsToValidate(doc) {
continue;
}

if (_pathType.$isMongooseDocumentArray) {
for (const p of paths) {
if (p === null || p.startsWith(_pathType.path + '.')) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is strict equality in p === null intended, or did you mean p == null?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ine 2487 we also have strill null check

@AbdelrahmanHafez
Copy link
Collaborator

LGTM, thanks. 👍

Frankly, I've always found it difficult to tell the difference between Subdocument, embedded documents, and arrays of documents.
If we were to design mongoose with the knowledge we have today, is there a way we can have logic apply to all cases?

Copy link
Collaborator

@Uzlopak Uzlopak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have some tests please :)?

lib/document.js Outdated
@@ -2505,6 +2505,14 @@ function _getPathsToValidate(doc) {
continue;
}

if (_pathType.$isMongooseDocumentArray) {
for (const p of paths) {
if (p === null || p.startsWith(_pathType.path + '.')) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ine 2487 we also have strill null check

} else {
err.path = updates[i];
validationErrors.push(err);
}
return callback(null);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can remove this line, as we anyway go to line 141?

@vkarpov15 vkarpov15 changed the base branch from master to 6.4 June 13, 2022 18:42
@vkarpov15
Copy link
Collaborator Author

@AbdelrahmanHafez we did some work to consolidate array subdocuments and single nested subdocuments for 6.0. Now, ArraySubdocument extends from Subdocument. Bringing nested paths into that mix would be very tricky, because nested paths are by design not subdocuments.

@vkarpov15 vkarpov15 merged commit 40626d1 into 6.4 Jun 13, 2022
@vkarpov15 vkarpov15 deleted the gh-11770 branch June 13, 2022 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make $__reset() not mark paths as init
3 participants