From edad51b2fafc022c1cc0a7578731f92fc1cd2559 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Sat, 20 May 2023 14:51:13 -0400 Subject: [PATCH] fix(array): track correct changes when setting nested array of primitives Fix #13372 --- lib/schema/array.js | 6 +++++- test/schema.test.js | 2 +- test/types.array.test.js | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/schema/array.js b/lib/schema/array.js index a33b4e497cb..5a621ba6aac 100644 --- a/lib/schema/array.js +++ b/lib/schema/array.js @@ -359,7 +359,11 @@ SchemaArray.prototype.cast = function(value, doc, init, prev, options) { options = options || emptyOpts; let rawValue = utils.isMongooseArray(value) ? value.__array : value; - value = MongooseArray(rawValue, options.path || this._arrayPath || this.path, doc, this); + let path = options.path || this.path; + if (options.arrayPathIndex != null) { + path += '.' + options.arrayPathIndex; + } + value = MongooseArray(rawValue, path, doc, this); rawValue = value.__array; if (init && doc != null && doc.$__ != null && doc.$populated(this.path)) { diff --git a/test/schema.test.js b/test/schema.test.js index af085121c59..8752374b866 100644 --- a/test/schema.test.js +++ b/test/schema.test.js @@ -2562,7 +2562,7 @@ describe('schema', function() { }); const casted = schema.path('ids').cast([[]]); - assert.equal(casted[0].$path(), 'ids.$'); + assert.equal(casted[0].$path(), 'ids.0'); }); describe('cast option (gh-8407)', function() { diff --git a/test/types.array.test.js b/test/types.array.test.js index 5c7381ca203..219d2df01ed 100644 --- a/test/types.array.test.js +++ b/test/types.array.test.js @@ -1899,4 +1899,18 @@ describe('types array', function() { m.Schema.Types.Array.options.castNonArrays = true; }); + + it('supports setting nested arrays directly (gh-13372)', async function() { + const Test = db.model('Test', new Schema({ intArr: [[Number]] })); + + const intArr = [[1, 2], [3, 4]]; + const doc = Test.hydrate({ intArr }); + + doc.intArr[1][1] = 5; + assert.deepStrictEqual(doc.getChanges(), { + $set: { + 'intArr.1.1': 5 + } + }); + }); });