Reputation: 304
I know that there shouldn't be any validation on field update but it runs anyway when I try to migrate a database.
Part of the migration:
const arr = await User.find({ ban: { $exists: true } });
arr.forEach(async item => {
// this works
// await User.updateOne({ _id: item._id }, { ban: false });
// this doesn't
item.ban = false;
await item.save();
});
Part of the schema:
email: {
type: String,
validate: {
validator: email => User.doesntExist({ email }),
message: ({ value }) => `Email ${value} has already been taken`
}
}
"ValidationError: User validation failed: email: Email [email protected] has already been taken"
Upvotes: 0
Views: 453
Reputation: 216
There is an option for disabling validator to be fired in mongoose save()
, which is validateBeforeSave
. (since mongoose version 4.4.2)
So try to use save({ validateBeforeSave: false })
if you want to keep using save()
instead of update()
.
Upvotes: 1
Reputation: 16294
You're doing it right, because as reported in mongoose documentation:
The save() function is generally the right way to update a document with Mongoose. With save(), you get full validation and middleware.
But, when you call the .save()
function, all validators are called, including your user email validator:
validator: email => User.doesntExist({ email })
And in your case this is a problem, because the user being validated is already saved in the db... So, to avoid this you need to use the .update() function in order to update your users.
Upvotes: 1
Reputation: 31
https://mongoosejs.com/docs/validation.html#validation
Validation is middleware. Mongoose registers validation as a pre('save') hook on every schema by default.
updateOne doesn't triggers save hook.
Upvotes: 0