Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Mongoose doesn't validate on update?

Tags:

mongoose

I have this code

var ClientSchema = new Schema({   name: {type: String, required: true, trim: true} });  var Client = mongoose.model('Client', ClientSchema); 

Using express, I create a new client with this code

var client = new Client(req.body); client.save(function(err, data) {   .... }); 

If I leave the name field empty on the form, mongoose doesn't allow to create the client because I set it as required on the schema. Also, if I leave spaces before and after the name, mongoose delete that spaces before save.

Now, I try to update a client with this code

var id = req.params.id; var client = req.body; Client.update({_id: id}, client, function(err) {   .... }); 

It let me to change the name, but if I leave it empty on the form, mongoose doesn't validate and save an empty name. If I add empty spaces before and after the name, it save the name with spaces.

Why mongoose validate on save but not on update? I'm doing it in the wrong way?

mongodb: 2.4.0 mongoose: 3.6.0 express: 3.1.0 node: 0.10.1

like image 993
Camilo Avatar asked Mar 26 '13 01:03

Camilo


People also ask

Can you update a Mongoose?

Updating Using QueriesThe save() function is generally the right way to update a document with Mongoose. With save() , you get full validation and middleware.

Does Mongoose have built-in validation?

Mongoose has several built-in validators. All SchemaTypes have the built-in required validator. The required validator uses the SchemaType's checkRequired() function to determine if the value satisfies the required validator. Numbers have min and max validators.

Is Mongoose validation enough?

If the validation logic is simple and small, there is no problem about mongoose validation. But in case of complex validation rules and multiple fields, then express-validator may be better choice. If the mongoose built-in validators are not enough for your validation logic, you have to create custom validators.

Does update call save in Mongoose?

When you create an instance of a Mongoose model using new , calling save() makes Mongoose insert a new document. If you load an existing document from the database and modify it, save() updates the existing document instead.


2 Answers

As of Mongoose 4.0 you can run validators on update() and findOneAndUpdate() using the new flag runValidators: true.

Mongoose 4.0 introduces an option to run validators on update() and findOneAndUpdate() calls. Turning this option on will run validators for all fields that your update() call tries to $set or $unset.

For example, given OP's Schema:

const ClientSchema = new Schema({   name: {type: String, required: true, trim: true} });  const Client = mongoose.model('Client', ClientSchema); 

Passing the flag on each update

You can use the new flag like this:

const id = req.params.id; const client = req.body; Client.update({_id: id}, client, { runValidators: true }, function(err) {   .... }); 

Using the flag on a pre hook

If you don't want to set the flag every time you update something, you can set a pre hook for findOneAndUpdate():

// Pre hook for `findOneAndUpdate` ClientSchema.pre('findOneAndUpdate', function(next) {   this.options.runValidators = true;   next(); }); 

Then you can update() using the validators without passing the runValidators flag every time.

like image 97
victorkt Avatar answered Sep 25 '22 02:09

victorkt


You're not doing anything wrong, validation is implemented as internal middleware within Mongoose and middleware doesn't get executed during an update as that's basically a pass-through to the native driver.

If you want your client update validated you'll need to find the object to update, apply the new property values to it (see underscore's extend method), and then call save on it.

Mongoose 4.0 Update

As noted in the comments and victorkohl's answer, Mongoose now support the validation of the fields of $set and $unset operators when you include the runValidators: true option in the update call.

like image 31
JohnnyHK Avatar answered Sep 23 '22 02:09

JohnnyHK