Подтвердить что ты не робот

Выборочная проверка 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 - это функция, которая сравнивает две даты.

4b9b3361

Ответ 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);