0

I would an unified method to validate my schemas assuming a user input, so not only apply the built-in validation on save/update, but also on find(), etc..

var User = mongoose.model("User", new Schema({
    name:   {type: String, minlength: 5, maxlength: 128, required: true, unique: true});
}));

What I want is to run validators every time before I run the queries with mongoose, to assure that the user inputs comply with the global schema rules.

Something like that in my route:

var username = $.get["username"], //An input from GET querystring

User = mongoose.model("User");

User.validate({name: username}, function(err) {
    if (err) return console.log("not valid input"); //i.e. too short

    //run query if valid
});

Is there a plugin (assumed that I'm not using Express) or maybe other already included in mongoose for that?

1 Answer 1

1

Documentation: http://mongoosejs.com/docs/validation.html It is supported in mongoose by default. If you are looking for generic validation before each save operation you can specify the field to be validated path and the validation validate(function(valueEntered, howToRespond). If the validation is not passed the error will be thrown as shown in the example below.

Example: Using bluebird for sake of convenience. The following snippet validates the email, before every save operation.

var mongoose = require('bluebird').promisifyAll(require('mongoose'));
var Schema = mongoose.Schema;
var UserSchema = new Schema({
  name: String,
  email: {
    type: String,
    lowercase: true
  },
  password: String,
});

UserSchema
  .path('email')
  .validate(function(value, respond) {
    var self = this;
    return this.constructor.findOneAsync({ email: value })
      .then(function(user) {
        if (user) {
          if (self.id === user.id) {
            return respond(true);
          }
          return respond(false);
        }
        return respond(true);
      })
      .catch(function(err) {
        throw err;
      });
  }, 'The specified email address is already in use.');

Sign up to request clarification or add additional context in comments.

4 Comments

The build-in validation is only applied on $set/$unset operations, so it does not meets the question's requirements.
don't quite get it, what is the use case for find validation. An example would be nice
new Schema({name: {type: String, trim: true, required: true, lowercase: true}}); Let's say the user gives as input a name with untrimmed spaces; without validation and casting, the input string will not be trimmed and the query will not give the correct result.. or maybe if the input have to be lowercased before the query.. or even, if the user gives an empty input and the schema requires that the string is not empty, the query will be executed the same. I know that I could simply put a condition before the query, but that will not be a global validation/casting/etc.. as per question :)
You can certainly implement custom find method, but it is not relevant to validation. Validation by definition should only be applied on save/update operations. If you need to add some custom methods to the model, you can use statics. For instance: UserSchema.statics.findByName = function (name, cb) { return this.find({ name: new RegExp(name, 'i') }, cb); }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.