Выборочная проверка mongoose с использованием 2 полей
Я хочу использовать пользовательскую проверку mongoose для проверки того, будет ли endDate больше, чем startDate. Как я могу получить доступ к значению startDate? При использовании this.startDate он не работает; Я получаю undefined.
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
- это функция, которая сравнивает две даты.
Ответы
Ответ 1
Вы можете попробовать вложить свои штампы даты в родительский объект, а затем проверить родительский объект. Например, что-то вроде:
//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}
});
Ответ 2
Вы можете сделать это с помощью Mongoose 'validate'
middleware, чтобы у вас был доступ ко всем полям:
ASchema.pre('validate', function(next) {
if (this.startDate > this.endDate) {
next(new Error('End Date must be greater than Start Date'));
} else {
next();
}
});
Обратите внимание, что вы должны обернуть сообщение об ошибке проверки в объекте JavaScript Error
при вызове next
, чтобы сообщить об ошибке проверки.
Ответ 3
Альтернативой принятому ответу на исходный вопрос является:
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;
}
Ответ 4
Я хотел расширить твердый ответ от @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. Помогает стандартизировать обработчики ошибок. Надеюсь, это поможет.
Ответ 5
Использование 'this' в валидаторе работает для меня - в этом случае при проверке уникальности адреса электронной почты мне нужно получить доступ к идентификатору текущего объекта, чтобы я мог исключить его из 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);
});
}
}
Ответ 6
Это решение, которое я использовал (спасибо @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);