mongoose custom validation using 2 fields

后端 未结 6 1481
余生分开走
余生分开走 2020-11-27 05:00

I want to use mongoose custom validation to validate if endDate is greater than startDate. How can I access startDate value? When using this.startDate, it d

相关标签:
6条回答
  • 2020-11-27 05:20

    An an alternative to the accepted answer for the original question is:

    var mongoose = require('mongoose'),
      Schema = mongoose.Schema;
    
    // schema definition
    var ASchema = new Schema({
      startDate: {
        type: Date,
        required: true
      },
      endDate: {
        type: Date,
        required: true,
        validate: [dateValidator, 'Start Date must be less than End Date']
      }
    });
    
    // function that validate the startDate and endDate
    function dateValidator(value) {
      // `this` is the mongoose document
      return this.startDate <= value;
    }

    0 讨论(0)
  • 2020-11-27 05:23

    You could try nesting your date stamps in a parent object and then validate the parent. For example something like:

    //create a simple object defining your dates
    var dateStampSchema = {
      startDate: {type:Date},
      endDate: {type:Date}
    };
    
    //validation function
    function checkDates(value) {
       return value.endDate < value.startDate; 
    }
    
    //now pass in the dateStampSchema object as the type for a schema field
    var schema = new Schema({
       dateInfo: {type:dateStampSchema, validate:checkDates}
    });
    
    0 讨论(0)
  • 2020-11-27 05:30

    You can do that using Mongoose 'validate' middleware so that you have access to all fields:

    ASchema.pre('validate', function(next) {
        if (this.startDate > this.endDate) {
            next(new Error('End Date must be greater than Start Date'));
        } else {
            next();
        }
    });
    

    Note that you must wrap your validation error message in a JavaScript Error object when calling next to report a validation failure. 

    0 讨论(0)
  • 2020-11-27 05:34

    This is the solution I used (thanks to @shakinfree for the hint) :

    var mongoose = require('mongoose'),
    Schema = mongoose.Schema;
    
    // schema definition
    var ASchema = new Schema({
      dateSchema : {
                    type:{
                        startDate:{type:Date, required: true}, 
                        endDate:{type:Date, required: true}
                    }, 
                    required: true, 
                    validate: [dateValidator, 'Start Date must be less than End Date']
                }
    });
    
    // function that validate the startDate and endDate
    function dateValidator (value) {
        return value.startDate <= value.endDate;
    }
    
    module.exports = mongoose.model('A', ASchema);
    
    0 讨论(0)
  • 2020-11-27 05:36

    I wanted to expand upon the solid answer from @JohnnyHK (thank you) by tapping into this.invalidate:

    Schema.pre('validate', function (next) {
      if (this.startDate > this.endDate) {
        this.invalidate('startDate', 'Start date must be less than end date.', this.startDate);
      }
    
      next();
    });
    

    This keeps all of the validation errors inside of a mongoose.Error.ValidationError error. Helps to keep error handlers standardized. Hope this helps.

    0 讨论(0)
  • 2020-11-27 05:45

    Using 'this' within the validator works for me - in this case when checking the uniqueness of email address I need to access the id of the current object so that I can exclude it from the count:

    var userSchema = new mongoose.Schema({
      id: String,
      name: { type: String, required: true},
      email: {
        type: String,
        index: {
          unique: true, dropDups: true
        },
        validate: [
          { validator: validator.isEmail, msg: 'invalid email address'},
          { validator: isEmailUnique, msg: 'Email already exists'}
        ]},
      facebookId: String,
      googleId: String,
      admin: Boolean
    });
    
    function isEmailUnique(value, done) {
      if (value) {
        mongoose.models['users'].count({ _id: {'$ne': this._id }, email: value }, function (err, count) {
          if (err) {
            return done(err);
          }
          // If `count` is greater than zero, "invalidate"
          done(!count);
        });
      }
    }
    
    0 讨论(0)
提交回复
热议问题