我一直在尝试运行自定义验证器,以检查用户输入的名称是否已存在于数据库中。由于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并将其分配给现有的数据库文档。
我不认为这是理想的方法,但是就目前而言,直到Mongoose提出支持自定义验证器的方法之前,我们都可以使用它来解决我们的问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句