node.js 使用 2 个字段的猫鼬自定义验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23760253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 17:21:51  来源:igfitidea点击:

mongoose custom validation using 2 fields

node.jsmongodbexpressmongoose

提问by amgohan

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 doesn't work; I get undefined.

我想使用猫鼬自定义验证来验证 endDate 是否大于 startDate。如何访问 startDate 值?使用this.startDate 时,它不起作用;我得到未定义。

var a = new Schema({
  startDate: Date,
  endDate: Date
});

var A = mongoose.model('A', a);

A.schema.path('endDate').validate(function (value) {
  return diff(this.startDate, value) >= 0;
}, 'End Date must be greater than Start Date');

diffis a function that compares two dates.

diff是一个比较两个日期的函数。

采纳答案by Tom Makin

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}
});

回答by JohnnyHK

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

您可以使用 Mongoose'validate'中间件来做到这一点,以便您可以访问所有字段:

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 Errorobject when calling nextto report a validation failure. 

请注意,Error在调用next以报告验证失败时,您必须将验证错误消息包装在 JavaScript对象中。 

回答by Jason Cust

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;
}

回答by kognizant

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

我想通过利用 this.invalidate 来扩展@JohnnyHK(谢谢)的可靠答案:

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.

这将所有验证错误保留在 mongoose.Error.ValidationError 错误中。有助于保持错误处理程序标准化。希望这可以帮助。

回答by prule

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:

在验证器中使用“this”对我有用 - 在这种情况下,在检查电子邮件地址的唯一性时,我需要访问当前对象的 id,以便我可以将其从计数中排除:

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);
    });
  }
}

回答by amgohan

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

这是我使用的解决方案(感谢@shakinfree 的提示):

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);