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

Schema.pre('save') Not Working With Update Function #2672

Closed
bentinata opened this issue Feb 12, 2015 · 9 comments
Closed

Schema.pre('save') Not Working With Update Function #2672

bentinata opened this issue Feb 12, 2015 · 9 comments

Comments

@bentinata
Copy link

I was testing with upsert option when I realize, upsert insert when called by Schema.update would not call schema.pre('save') middleware. Haven't done much test though.

How to reproduce:

Use update function with upsert option.

Schema.update(query, doc, {upsert: true}, function(){});

On respective schema model, use some plugin.

Schema.plugin(plugin.use);

Plugin pre('save') function wouldn't called.

exports.use= function (schema, options) {

  schema.pre('save', function (next) {
    console.log('this wouldn't show up');
    next();
  });
};

I don't know if this is a bug, or there's some flaw in my code. Currently not affecting much my code, but some explanation would be appreciated. Thanks. :)

@Swissbite
Copy link

update does a regular mongo driver call. Schema.update bypass the middleware by design.

In the notes of the documentation to Model.update is defined what is not applyed.

  • defaults
  • setters
  • validators
  • middleware

If you want to get sure that your hooks are called, you have to get your model from DB (or hold it), edit it and use the save method on the model instance.

@vkarpov15
Copy link
Collaborator

pre('save') gets executed before a save() call. update() is not the same function as save(). However, 4.0.0-rc2 does have support for pre('update') hooks :)

@bentinata
Copy link
Author

Oh, thanks for the clarification. I thought that because I use upsert function, It'll call save() method. Thanks. :)

@ajbraus
Copy link

ajbraus commented Nov 24, 2018

This is misleading. pre('update') does not behave like pre('save') because the 'this' in the pre('update') is just the query and you cannot call useful functions like this.isNew or this.isModified() on it. pre('save') should be called either when creating or updating an object, because in either case one is "saving" the object.

@ajbraus
Copy link

ajbraus commented Nov 24, 2018

Right now a lot of people are following this code for password hashing

https://stackoverflow.com/questions/14588032/mongoose-password-hashing

The assumption I (and I would be many others have) is that every time a user saves their user record this pre('save') is called.

Since we see here that this is not the case, if anyone changes their password, the password will not be salted and hashed.

I guess the work around is to always first call a find() then a save() and never use the update() functions at all. Seems like mongoose doesn't even need all the "update" style functions at all then since they are so dangerous and poorly documented.

@vkarpov15
Copy link
Collaborator

@ajbraus what if we added an official plugin?

@ajbraus
Copy link

ajbraus commented Dec 4, 2018

Sure @vkarpov15 - what does that entail? How do we get started? :D

@vkarpov15
Copy link
Collaborator

@ajbraus Mongoose has some officially supported plugins. They're separate projects that have functionality that we want to support but not necessarily put into mongoose core. If you're interested in writing a plugin, you're more than welcome to give it a shot:

Plugins docs

@petatemarvin26
Copy link

petatemarvin26 commented Jul 3, 2021

same issue and I done by solving it 'updateOne', and I update my answer here

@Automattic Automattic locked and limited conversation to collaborators Jul 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants