Skip to content

Commit 403a28e

Browse files
committed
fix: add ignoreAtomics option to isModified() for better backwards compatibility with Mongoose 5
Re: #14024
1 parent 8e141d1 commit 403a28e

File tree

3 files changed

+53
-6
lines changed

3 files changed

+53
-6
lines changed

lib/document.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2223,8 +2223,9 @@ Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;
22232223
* @api public
22242224
*/
22252225

2226-
Document.prototype.isModified = function(paths, modifiedPaths) {
2226+
Document.prototype.isModified = function(paths, options, modifiedPaths) {
22272227
if (paths) {
2228+
const ignoreAtomics = options && options.ignoreAtomics;
22282229
const directModifiedPathsObj = this.$__.activePaths.states.modify;
22292230
if (directModifiedPathsObj == null) {
22302231
return false;
@@ -2245,7 +2246,16 @@ Document.prototype.isModified = function(paths, modifiedPaths) {
22452246
return !!~modified.indexOf(path);
22462247
});
22472248

2248-
const directModifiedPaths = Object.keys(directModifiedPathsObj);
2249+
let directModifiedPaths = Object.keys(directModifiedPathsObj);
2250+
if (ignoreAtomics) {
2251+
directModifiedPaths = directModifiedPaths.filter(path => {
2252+
const value = this.$__getValue(path);
2253+
if (value != null && value[arrayAtomicsSymbol] != null && value[arrayAtomicsSymbol].$set === undefined) {
2254+
return false;
2255+
}
2256+
return true;
2257+
});
2258+
}
22492259
return isModifiedChild || paths.some(function(path) {
22502260
return directModifiedPaths.some(function(mod) {
22512261
return mod === path || path.startsWith(mod + '.');
@@ -2679,7 +2689,7 @@ function _getPathsToValidate(doc) {
26792689
paths.delete(fullPathToSubdoc + '.' + modifiedPath);
26802690
}
26812691

2682-
if (doc.$isModified(fullPathToSubdoc, modifiedPaths) &&
2692+
if (doc.$isModified(fullPathToSubdoc, null, modifiedPaths) &&
26832693
!doc.isDirectModified(fullPathToSubdoc) &&
26842694
!doc.$isDefault(fullPathToSubdoc)) {
26852695
paths.add(fullPathToSubdoc);

lib/types/subdocument.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ Subdocument.prototype.markModified = function(path) {
178178
* ignore
179179
*/
180180

181-
Subdocument.prototype.isModified = function(paths, modifiedPaths) {
181+
Subdocument.prototype.isModified = function(paths, options, modifiedPaths) {
182182
const parent = this.$parent();
183183
if (parent != null) {
184184
if (Array.isArray(paths) || typeof paths === 'string') {
@@ -188,10 +188,10 @@ Subdocument.prototype.isModified = function(paths, modifiedPaths) {
188188
paths = this.$__pathRelativeToParent();
189189
}
190190

191-
return parent.$isModified(paths, modifiedPaths);
191+
return parent.$isModified(paths, options, modifiedPaths);
192192
}
193193

194-
return Document.prototype.isModified.call(this, paths, modifiedPaths);
194+
return Document.prototype.isModified.call(this, paths, options, modifiedPaths);
195195
};
196196

197197
/**

test/document.modified.test.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,43 @@ describe('document modified', function() {
208208
assert.equal(post.isModified('comments.0.title'), true);
209209
assert.equal(post.isDirectModified('comments.0.title'), true);
210210
});
211+
it('with push (gh-14024)', async function() {
212+
const post = new BlogPost();
213+
post.init({
214+
title: 'Test',
215+
slug: 'test',
216+
comments: [{ title: 'Test', date: new Date(), body: 'Test' }]
217+
});
218+
219+
post.comments.push({ title: 'new comment', body: 'test' });
220+
221+
assert.equal(post.isModified('comments.0.title', { ignoreAtomics: true }), false);
222+
assert.equal(post.isModified('comments.0.body', { ignoreAtomics: true }), false);
223+
assert.equal(post.get('comments')[0].isModified('body', { ignoreAtomics: true }), false);
224+
});
225+
it('with push and set (gh-14024)', async function() {
226+
const post = new BlogPost();
227+
post.init({
228+
title: 'Test',
229+
slug: 'test',
230+
comments: [{ title: 'Test', date: new Date(), body: 'Test' }]
231+
});
232+
233+
post.comments.push({ title: 'new comment', body: 'test' });
234+
post.get('comments')[0].set('title', 'Woot');
235+
236+
assert.equal(post.isModified('comments', { ignoreAtomics: true }), true);
237+
assert.equal(post.isModified('comments.0.title', { ignoreAtomics: true }), true);
238+
assert.equal(post.isDirectModified('comments.0.title'), true);
239+
assert.equal(post.isDirectModified('comments.0.body'), false);
240+
assert.equal(post.isModified('comments.0.body', { ignoreAtomics: true }), false);
241+
242+
assert.equal(post.isModified('comments', { ignoreAtomics: true }), true);
243+
assert.equal(post.isModified('comments.0.title', { ignoreAtomics: true }), true);
244+
assert.equal(post.isDirectModified('comments.0.title'), true);
245+
assert.equal(post.isDirectModified('comments.0.body'), false);
246+
assert.equal(post.isModified('comments.0.body', { ignoreAtomics: true }), false);
247+
});
211248
it('with accessors', function() {
212249
const post = new BlogPost();
213250
post.init({

0 commit comments

Comments
 (0)