-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
pre, post middleware are not executed on findByIdAndUpdate #964
Comments
by design. there are docs involved to call hooks on. |
correction, there are no docs to call hooks on. |
So? If I want to call pre, post middleware I need to use the first approach? |
yes that is correct. Model.update,findByIdAndUpdate,findOneAndUpdate,findOneAndRemove,findByIdAndRemove are all commands executed directly in the database. |
This should definitely be clarified in the guide, especially if you're talking about validation in that same page and describing |
if you click on the link "better" it takes you to the full documentation of feel free to send a pull request to add something you feel is better. its On Wed, Oct 31, 2012 at 6:03 PM, Jesse Fulton notifications@github.comwrote:
Aaron |
Added notes to the middleware doc Pull request: #1750 |
Hello, I know the issue is closed, but I am not entirely satisfied with the answer. Shouldn't there be at least a post-save or post-update middleware for findOneAndUpdate and other similar operations ? Is seems ok since the document is returned. Not feasible for pre middlewares or for Model.update, i agree. It would greatly improve the capabilities of plugins such as mongoosastic that is currently blind to some operations it should be able to support. If no middleware, does someone have an idea on how to manage some post update operations in a plugin ? Thanks |
@albanm certain methods bypass mongoose completely, so you don't get the middleware hooks. AFAIK, the only way to get the hooks to execute is to use separate |
I get that and it makes sense. Pre middlewares are out of question as there is no fetching prior to certain methods. But still, mongoose should be able to wrap the update operations that also return the updated documents and trigger some post hooks. |
I think @albanm is right, People may want the same functionality when they use the same function. How about wrap those 'directly update' methods with some interception of check that if there's any hooks exist? If hook exist, use it, or call original update methods otherwise. |
+1 |
2 similar comments
+1 |
+1 |
+1 |
👍 |
+1 |
👎 I would however, 👍 if I was able to disable middleware on a save call. I often find myself with a mongoose object that was passed from another function and simply want to perform a .save - in this situation, doing a .save is preferable to writing a new query. If this is possible, please point it out Either way, amazing library. Kudos to awesome maintainers. Not sure how I would operate without it. |
+1 |
A simple way to add hooks for these method is overwrite the embed functions: _update = UserModel.update
UserModel.update = (conditions, update) ->
update.updatedAt or= new Date
_update.apply this, arguments Then every update call of mongoose will fix the updatedAt key of data. You may give a try of this model limbo. It is a simple wrapper of mongoose model, supporting bind static/method/overwrite to all the schemas, and call rpc methods to query the mongodb. |
@nlonguit I guess it will. But you can access through
|
This code is working well for me. Thanks @akoskm |
I wonder if it would be possible to add a pre hook for findByIdAndUpdate as well. Would be nice to have both hooks available. |
I did it this way and it is working: Just findById then save without updating any fields then use the findByIdAndUpdate method:
|
I'm trying to set a property to have the length of an array.
The correct length is logged, although the query never sets totalNumberOfComments, and the field stays at 0 (since the schema references default: 0). When I
Although when I turn on debug mode, a query is never logged by Mongoose. Is there something I'm doing wrong, or is this a bug? |
@zilions |
@vkarpov15 Ahhhh right! Then I can just use For example:
Will trigger the following hook:
Although, the hook will |
Because you're technically executing the same query - schema.post('findOneAndUpdate', function(result) {
this.update({}, {
totalNumberOfComments: result.comments.length
}).exec();
})); is essentially the same as var query = Post.findOneAndUpdate({_id: fj394hri3hfj}, {$push: {comments: myNewComment}});
query.update({}, {
totalNumberOfComments: result.comments.length
}).exec();
query.findOneAndUpdate().exec(); If you want to create a new query from scratch, just do schema.post('findOneAndUpdate', function(result) {
this.model.update({}, { // <--- `this.model` gives you access to the `Post` model
totalNumberOfComments: result.comments.length
}).exec();
})); |
just dont touch your pre save hook,
|
I found that the order matters in which you define a model and define a Does not work:
Does work:
Hope this helps anyone! |
I just found out the same thing as @nicky-lenaers. It works just fine with Is there a workaround do define a |
@albert-92 no not at the moment |
For anyone trying to get something that used to be like SCHEMA.pre('validate', function(done) {
// and here use something like
this.yourNestedElement
// to change a value or maybe create a hashed character
done();
}); This should work SCHEMA.pre('findOneAndUpdate', function(done){
this._update.yourNestedElement
done();
}); |
I can't get post hooks to update the document in the collection. `module.exports = function (mongoose) {
}`
Sets field in collection to { id:1, field1: 'test' ) but should be {id: 1, field1: 'test', field2:'New Value'} I can change change the result of the findOneAndUpdate by doing this |
I think it might be that you are trying to update the model with an element that already exists on the model. Or possibly that you are selecting it wrong. Try printing out "this" in your mySchema.post. Also you don't seem to have a done() or next() in your post. I'm not very knowledgable on the subject but I know printing out this will at least give you an idea of what you are dealing with. |
Isn't the point of update to change an existing document in your model? this is a query object You don't need done or next in post hooks as far as I understand. |
Well you have this.model.update which is the schema not the model of the object. I think.. Which means you would have to use mySchema.post('findOneAndUpdate', function (result) {
this.model.update({}, {
$set: { field2: 'New Value'}
}).exec();
});
return mySchema; This seems a little backwards to be calling a model function inside of the model. Since you could just use parts of the "this" object that is given to you. you might be better off just using the findOneAndUpdate instead of calling it and then calling another model function on top of it. var data = yourNewData;
self.findOneAndUpdate({id: something._id}, data, {safe: false, new: true})
.exec()
.then(resolve)
.catch(reject); In my example above I used this._update because that was the update object that needed to be used off of this. |
I have tried using $set. It still doesn't change my document in the collection. |
Mongoose findOneAndUpdate bypasses hooks Automattic/mongoose#964
Where can I find the all available pre and post hooks? |
Middleware docs http://mongoosejs.com/docs/middleware.html |
+1 |
Because a findAndUpdate method is presented to cut down the following code:
to this:
We need to use pre, post middleware exactly the same. At now pre, post middleware are not executed when I make findByIdAndUpdate.
The text was updated successfully, but these errors were encountered: