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

feat: pathsToSave option to save() function #14385

Merged
merged 10 commits into from Mar 20, 2024
9 changes: 6 additions & 3 deletions lib/model.js
Expand Up @@ -298,7 +298,6 @@ Model.prototype.$__handleSave = function(options, callback) {
if (!saveOptions.hasOwnProperty('session') && session != null) {
saveOptions.session = session;
}

if (this.$isNew) {
// send entire doc
const obj = this.toObject(saveToObjectOptions);
Expand Down Expand Up @@ -511,6 +510,7 @@ function generateVersionError(doc, modifiedPaths) {
* @param {Number} [options.wtimeout] sets a [timeout for the write concern](https://www.mongodb.com/docs/manual/reference/write-concern/#wtimeout). Overrides the [schema-level `writeConcern` option](https://mongoosejs.com/docs/guide.html#writeConcern).
* @param {Boolean} [options.checkKeys=true] the MongoDB driver prevents you from saving keys that start with '$' or contain '.' by default. Set this option to `false` to skip that check. See [restrictions on field names](https://docs.mongodb.com/manual/reference/limits/#mongodb-limit-Restrictions-on-Field-Names)
* @param {Boolean} [options.timestamps=true] if `false` and [timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this `save()`.
* @param {Array} [options.pathsToSave] An array of paths that tell mongoose to only validate and save the paths in `pathsToSave`.
* @throws {DocumentNotFoundError} if this [save updates an existing document](https://mongoosejs.com/docs/api/document.html#Document.prototype.isNew) but the document doesn't exist in the database. For example, you will get this error if the document is [deleted between when you retrieved the document and when you saved it](documents.html#updating).
* @return {Promise}
* @api public
Expand Down Expand Up @@ -736,8 +736,11 @@ function handleAtomics(self, where, delta, data, value) {
*/

Model.prototype.$__delta = function() {
const dirty = this.$__dirty();

let dirty = this.$__dirty();
if (this.$__.saveOptions && this.$__.saveOptions.pathsToSave) {
IslandRhythms marked this conversation as resolved.
Show resolved Hide resolved
const pathsToSave = this.$__.saveOptions.pathsToSave;
dirty = dirty.filter(x => pathsToSave.includes(x.path));
}
const optimisticConcurrency = this.$__schema.options.optimisticConcurrency;
if (optimisticConcurrency) {
if (Array.isArray(optimisticConcurrency)) {
Expand Down
12 changes: 12 additions & 0 deletions test/model.test.js
Expand Up @@ -2537,6 +2537,18 @@ describe('Model', function() {
assert.ok(!doc.$__.$versionError);
assert.ok(!doc.$__.saveOptions);
});
it('should only save paths specificed in the `pathsToSave` array (gh-9583)', async function() {
const schema = new Schema({ name: String, age: Number, weight: Number, location: String });
const Test = db.model('Test', schema);
await Test.create({ name: 'Test Testerson', age: 1, weight: 180, location: 'Florida' });
const doc = await Test.findOne();
doc.name = 'Test';
doc.age = 100;
IslandRhythms marked this conversation as resolved.
Show resolved Hide resolved
await doc.save({ pathsToSave: ['name'] });
const check = await Test.findOne();
assert.equal(check.name, 'Test');
assert.equal(check.age, 1);
});
});


Expand Down