在猫鼬更新查询中运行自定义验证

无敌公爵夫人

我一直在尝试运行自定义验证器,以检查用户输入的名称是否已存在于数据库中。由于mongoDb将大写和小写名称视为不同,因此我为此创建了自己的验证器。

function uniqueFieldInsensitive ( modelName, field ){
return function(val, cb){
    if( val && val.length ){ // if string not empty/null

        var query = mongoose.models[modelName]
            .where( field, new RegExp('^'+val+'$', 'i') ); // lookup the collection for somthing that looks like this field

        if( !this.isNew ){ // if update, make sure we are not colliding with itself
            query = query.where('_id').ne(this._id)
        }

        query.count(function(err,n){
            // false when validation fails
            cb( n < 1 )
        })
    } else { // raise error of unique if empty // may be confusing, but is rightful
        cb( false )
    }
}

}

现在,问题是验证程序在将文档保存到数据库中时运行,而在更新时却没有。

由于我使用的是猫鼬版本4.x,因此我也尝试{ runValidators: true }在更新查询中使用。由于在更新时我的验证器中的'this'关键字为'null',因此该方法也不起作用,而在保存时它指的是更新后的文档。

您能否让我知道我是否错过了某些事情,或者是否可以通过其他任何方式在更新查询中运行自定义验证程序。

无敌公爵夫人

最终,我找到了解决方法。根据MongoDB文档,它说:

首先,更新验证器仅检查$ set和$ unset操作。更新验证程序将不会检查$ push或$ inc操作。第二个也是最重要的区别在于,在文档验证器中,这是指要更新的文档。对于更新验证器,由于没有基础文档,因此在您的自定义验证器中将为null。请参阅:Validator for update()

因此,现在只剩下在查询中调用save()而不是update()了。由于save()会调用所有自定义验证器和内置验证器,因此也会调用我们的验证器。我是这样实现的:

function(req, res, next) {
_.assign(req.libraryStep, req.body);

req.libraryStep.save().then(function(data){
    res.json(data);
}).then(null, function (err) {
    console.info(err);
    var newErr = new errorHandler.error.ProcessingError(errorHandler.getErrorMessage(err));
    next(newErr);
    });
};

注意这里req.libraryStep是我从数据库中查询的文档。我使用了lodash方法assign,该方法接受更新的json并将其分配给现有的数据库文档。

https://lodash.com/docs#assign

我不认为这是理想的方法,但是就目前而言,直到Mongoose提出支持自定义验证器的方法之前,我们都可以使用它来解决我们的问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章