From e0606f33fbb78bac32c92e9767c9f8b2742af780 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Fri, 21 Feb 2020 17:16:27 -0500 Subject: [PATCH] docs(middleware): clarify that updateOne and deleteOne hooks are query middleware by default, not document middleware Fix #8581 --- docs/middleware.pug | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/middleware.pug b/docs/middleware.pug index c232023c875..8122dec1eca 100644 --- a/docs/middleware.pug +++ b/docs/middleware.pug @@ -86,6 +86,13 @@ block content want to your middleware to run on [`Query.remove()`](./api.html#query_Query-remove) use [`schema.pre('remove', { query: true, document: false }, fn)`](./api.html#schema_Schema-pre). + **Note:** Unlike `schema.pre('remove')`, Mongoose registers `updateOne` and + `deleteOne` middleware on `Query#updateOne()` and `Query#deleteOne()` by default. + This means that both `doc.updateOne()` and `Model.updateOne()` trigger + `updateOne` hooks, but `this` refers to a query, not a document. To register + `updateOne` or `deleteOne` middleware as document middleware, use + `schema.pre('updateOne', { document: true, query: false })`. + **Note:** The [`create()`](./api.html#model_Model.create) function fires `save()` hooks.

Pre

@@ -371,7 +378,7 @@ block content ``` You **cannot** access the document being updated in `pre('updateOne')` or - `pre('findOneAndUpdate')` middleware. If you need to access the document + `pre('findOneAndUpdate')` query middleware. If you need to access the document that will be updated, you need to execute an explicit query for the document. ```javascript @@ -381,6 +388,25 @@ block content }); ``` + However, if you define `pre('updateOne')` document middleware, + `this` will be the document being updated. That's because `pre('updateOne')` + document middleware hooks into [`Document#updateOne()`](/docs/api/document.html#document_Document-updateOne) + rather than `Query#updateOne()`. + + ```javascript + schema.pre('updateOne', { document: true, query: false }, function() { + console.log('Updating'); + }); + const Model = mongoose.model('Test', schema); + + const doc = new Model(); + await doc.updateOne({ $set: { name: 'test' } }); // Prints "Updating" + + // Doesn't print "Updating", because `Query#updateOne()` doesn't fire + // document middleware. + await Model.updateOne({}, { $set: { name: 'test' } }); + ``` +

Error Handling Middleware

_New in 4.5.0_