Node.js Mongoose findByIdAndUpdate未对子文档运行验证
这是我的模型:Node.js Mongoose findByIdAndUpdate未对子文档运行验证,node.js,mongoose,Node.js,Mongoose,这是我的模型: 'use strict'; var nested = new Schema({ name: String }); var test = new Schema({ url : { type : String, // First validation validate : [validator.isURL, 'Invalid URL'] }, array : [ {
'use strict';
var nested = new Schema({
name: String
});
var test = new Schema({
url : {
type : String,
// First validation
validate : [validator.isURL, 'Invalid URL']
},
array : [
{
type: nested,
// Second Validation
validate: [function(value) {console.log("CALLED"); return value.length <=3;}, 'Too long']
}
]
});
module.exports = Parent.discriminator('Test', test);;
以下是最新消息:
Test.findByIdAndUpdate(id, {$set: {array: whatever}}, {new: true, runValidators: true}, function(err, model) {
if (err) {
return res.status(422).json(err);
}
res.status(200).json(model);
});
假设无论什么
在两种情况下都包含长度为4的数组(新建和更新)
当创建一个新模型时,两个验证都按预期工作,我得到一个错误。但是,当使用findbyidanddupdate
时,只运行第一次验证,忽略array
属性上的验证(甚至不调用)。给出了什么?根据,如果runValidators
设置为true,则验证器似乎仅适用于update()
和findOneAndUpdate()
您是否尝试过:
Test.findOneAndUpdate({_id: id}, {$set: {array: whatever}}, {new: true, runValidators: true}, function(err, model) {
if (err) {
return res.status(422).json(err);
}
res.status(200).json(model);
});
验证程序在findByIdAndUpdate上不起作用(不确定,但在我的情况下不起作用),您可以使用中间件来摆脱验证程序,但需要编写一些额外的代码 中间件将如下所示
[SCHEMA].pre('findOneAndUpdate', function(next){
// findOneAndUpdate and findByIdAndUpdate, will fire this hook
console.log(this.getUpdate()); // it will return the update Object
console.log(this.getQuery()); // it will return the query object
// Do all validation here and modify the update object
// this.getUpdate().url = 'stackoverflow.com';
// for sub-docs you need to use loop;
if(this.getUpdate() && Array.isArray(this.getUpdate().array))
this.getUpdate().array = this.getUpdate().array.map(function(val){
return (val.length <= 3) ? true : 'To Long';
});
// after all validation call next
next();
});
[SCHEMA].pre('findOneAndUpdate',函数(下一个){
//findOneAndUpdate和FindByAndUpdate将触发此钩子
console.log(this.getUpdate());//它将返回更新对象
console.log(this.getQuery());//它将返回查询对象
//在此处执行所有验证并修改更新对象
//this.getUpdate().url='stackoverflow.com';
//对于子文档,您需要使用循环;
if(this.getUpdate()&&Array.isArray(this.getUpdate().Array))
this.getUpdate().array=this.getUpdate().array.map(函数(val){
return(val.length不是在文档中解释的吗?findByIdAndUpdate忽略验证和钩子?(默认值、setter、验证程序和中间件都被忽略)它甚至运行了第一个验证器,这有点让人吃惊。@KevinB确实如此。runValidators
选项默认设置为false
,但我在代码中将其设置为true
,这可能允许运行第一个验证器,但不允许运行第二个(子文档上的一个)。它在我的模型上运行几乎所有的验证器,除了子文档数组上的验证器。有更好的方法吗?我需要通过PUT(实际上是补丁)更新我的文档,我能看到的另一种选择是使用find
,然后使用save
,这使得findbyiandupdate
的目的让我很困惑。如果使用$set
,那么this.getUpdate()
将给出这样的对象{$set:{array:[]}
[SCHEMA].pre('findOneAndUpdate', function(next){
// findOneAndUpdate and findByIdAndUpdate, will fire this hook
console.log(this.getUpdate()); // it will return the update Object
console.log(this.getQuery()); // it will return the query object
// Do all validation here and modify the update object
// this.getUpdate().url = 'stackoverflow.com';
// for sub-docs you need to use loop;
if(this.getUpdate() && Array.isArray(this.getUpdate().array))
this.getUpdate().array = this.getUpdate().array.map(function(val){
return (val.length <= 3) ? true : 'To Long';
});
// after all validation call next
next();
});