猫鼬验证 - 执行多个自定义验证

Mongoose Validation - perform multiple custom validations

我有一个基本的猫鼬模式:

var userSchema = new Schema({
    userName: {type: String, required: 'Please enter a username'},
    email: {type: String, required: 'Please enter email'},
    password: {type: String, required: 'Please create a password'},
    created: {type: Date, default: Date.now}
});

然后我执行一个自定义验证程序,调用一个小型服务(在另一个文件中)来查找电子邮件地址是否已在使用中:

userSchema.path('email').validate(function(value, next) {
    userService.findUser(value, function(err, user) {
        if (err) {
            console.log(err);
            return next(false);
        }
        next(!user);
    });
}, 'Already exists');

这是 findUser 方法:

exports.findUser = function(email, next) {
    User.findOne({email: email.toLowerCase()}, function(err, user) {
        next(err, user);
    });
};

我的问题是:如果我想使用像 validator 这样的模块来验证输入是否是电子邮件,我该怎么做?我知道我可以要求模块并执行 validator.isEmail(email) 之类的操作并在 return 中获取一个布尔值,但我如何将其与我当前的设置集成?

最简单的方法就是在 validate 方法中检查它。如果电子邮件无效,它将 return 验证错误。

var validator = require('validator');

// Validate email address
userSchema
  .path('email')
  .validate(function (value) {

    return validator.isEmail(value);

  }, 'Email is invalid');

这里有一些使用 constructor 检查电子邮件唯一性的建议:

// Validate that email is not taken
userSchema
  .path('email')
  .validate(function (value, respond) {
    var self = this;

    this.constructor.findOne({email: value}, function (err, user) {
      if (err) {
        return respond(false);
      }

      if (user) {
        if (self.id === user.id) {
          return respond(true);
        }
        return respond(false);
      }
      respond(true);
    });
  }, 'Already exists');

最简单的方法是在架构中使用 RegEx 来验证它是否是有效的电子邮件。然后使用 UserSchema.pre('save' function...) 验证电子邮件是否已在使用中。这将充当在注册方法中调用的中间件。

var userSchema = new Schema({
    userName: {type: String, required: 'Please enter a username'},
    email: {type: String, required: 'Please enter email'},
    password: {
           type: String, 
           match: [/.+\@.+\..+/, "Please fill a valid email address"], 
           required: 'Please create a password'},
           created: {type: Date, default: Date.now}
});