0

我正在尝试在 NodeJS/ExpressJS/MongoDB/Mongoose 应用程序中使用验证器和 express-validator 来确认用户没有使用已注册的电子邮件地址。我已经在电子邮件字段上有一个唯一索引,但我想做的是使用一种方法将所有验证保存在一个位置。因此,我的问题是:使用 express-validator 验证唯一性。

我已经创建了用于查找电子邮件地址的模式方法,并且它正在工作。我创建了自定义验证器,并将其连接到控制器中。它也在工作。我的问题是我不知道如何将回调中模式方法的结果与控制器中的验证器通信。

user.js(模型)

...

/**
 * Check for email addresses already in the collection
 */
 checkEmailDupes: function(req, cb) {
   this.model('User').findOne({email: req}, function (err, user) {
     if (err) {
       return cb(err);
     }
     cb(null, user); // this is passing back the expected result
   });
},

...

users.js(控制器)

...
// The call to the custom validator (shown below)
req.assert('email', 'Email must be unique').checkEmailDupes(user);
...

// Check for email addresses that are already registered
expressValidator.Validator.prototype.checkEmailDupes = function(user) {
  user.checkEmailDupes(this.str, function (err, result) {
    if (err) {
      console.log('An error occurred in checkEmailDupes');
    }
    else {
      console.log('Found a user in checkEmailDupes');
      console.log(result); // this is producing the expected result
    }
  });
  return this.error(this.msg || 'Looks like this email address has already been registered');
  return this;
}

我知道return this.error(this.msg...)需要去其他地方。理想情况下,我会将其放入回调中,但是当我这样做时,我会得到

TypeError: Object # has no method 'error'

4

2 回答 2

0

我最终无法让这种方法发挥作用。感谢@robertklep 和他的反馈,我决定使用 mongo 传回的错误代码(在为电子邮件找到非唯一值的情况下,它是MongoError: E11000 duplicate key error index)并基于此设置错误消息。

它最终看起来如下(在用户控制器中):

user.save(function(err) {
  if (err) {
    // Instantiate the errors array
    var errors = [];

    // Email address already in DB
    if (err.code == 11000) {
      // Build the error object
      var error = {
        param: 'email',
        msg: 'The email address entered has already been registered',
        value: ''
      };

      // Push the error onto the errors array
      errors.push(error);
    }

    return res.render('users/signup', {
      errors: errors,
      user: user
    });
  }

  ...
于 2013-09-30T17:13:28.957 回答
0

试试这个(所做的是创建一个error范围和第一个参数已经“填充”的部分函数):

expressValidator.Validator.prototype.checkEmailDupes = function(user) {
  var error = this.error.bind(this, this.msg || 'Looks like this email address has already been registered');

  user.checkEmailDupes(this.str, function (err, result) {
    if (err) {
      console.log('An error occurred in checkEmailDupes');
      return error();
    }
    else {
      console.log('Found a user in checkEmailDupes');
      console.log(result); // this is producing the expected result
    }
  });
  return this;
}

但是,这里可能存在一些问题,因为user.checkEmailDupes它是异步的,但expressValidator.Validator.prototype.checkEmailDupes不是。我不知道验证器模块的内部工作原理是否有问题。

编辑:也许我不久前给出的这个答案也可能有用。使用验证数据库约束express-validator可能不是最佳解决方案。

于 2013-09-30T07:58:19.380 回答