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
mongoose custom validation using 2 fields
提问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);

