mongoose自定义validation使用2个字段
我想使用mongoose自定义validation来validation,如果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');
diff
是比较两个date的函数。
您可以尝试将date标记嵌套在父对象中,然后validation父对象。 比如像这样的东西:
//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} });
您可以使用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(); } });
请注意, next
调用报告validation失败时,您必须将validation错误消息包装在JavaScript Error
对象中。
对原始问题的接受答案的替代scheme是:
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; }
我想通过@JohnnyHK(谢谢)通过攻击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(); });
这将保持mongoose.Error.ValidationError错误中的所有validation错误。 有助于保持error handling程序的标准化。 希望这可以帮助。
在validation器中使用“this”对我有效 – 在这种情况下,当检查电子邮件地址的唯一性时,我需要访问当前对象的ID,以便可以将其从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); }); } }
这是我使用的解决scheme(感谢@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);