为什么猫鼬不更新验证?

我有这个代码

var ClientSchema = new Schema({
  name: {type: String, required: true, trim: true}
});

var Client = mongoose.mode('Client', ClientSchema);

使用express,我用此代码创建一个新客户端

var client = new Client(req.body);
client.save(function(err, data) {
  ....
});

如果我在表单上将名称字段留空,则mongoose不允许创建客户端,因为我在架构上根据需要设置了该客户端。 另外,如果我在名称前后保留空格,猫鼬会在保存之前删除该空格。

现在,我尝试使用此代码更新客户端

var id = req.params.id;
var client = req.body;
Client.update({_id: id}, client, function(err) {
  ....
});

它允许我更改名称,但是如果我在表单上将其保留为空白,猫鼬将不会验证并保存一个空名称。 如果我在名称前后添加空格,则会使用空格保存名称。

为什么猫鼬在保存时验证而不在更新时验证? 我做错了吗?

mongodb的:2.4.0猫鼬:3.6.0快递:3.1.0节点:0.10.1

Camilo asked 2020-06-27T21:21:49Z
5个解决方案
72 votes

从猫鼬4.0开始,您可以使用新的标记2941972948279886886在update()runValidators上运行验证器。

猫鼬4.0引入了在2941972948279279886848和 runValidators致电。 启用此选项将运行验证器 您的update()呼叫尝试访问$set$unset的所有字段。

例如,给定OP的架构:

var ClientSchema = new Schema({
  name: {type: String, required: true, trim: true}
});

var Client = mongoose.model('Client', ClientSchema);

在每次更新时传递标志

您可以这样使用新标志:

var id = req.params.id;
var client = req.body;
Client.update({_id: id}, client, { runValidators: true }, function(err) {
  ....
});

update()挂钩上使用标志

如果您不想每次更新时都设置标志,则可以为runValidators设置update()钩子:

// Pre hook for `findOneAndUpdate`
ClientSchema.pre('findOneAndUpdate', function(next) {
  this.options.runValidators = true;
  next();
});

然后,您可以使用验证器update(),而无需每次都通过runValidators849标志。

victorkohl answered 2020-06-27T21:23:08Z
56 votes

您没有做错任何事情,validation被实现为Mongoose中的内部中间件,并且在$set期间不执行中间件,因为这基本上是对本机驱动程序的传递。

如果要验证客户端更新,则需要$set更新对象,对其应用新的属性值(请参见下划线的$set方法),然后在其上调用$unset

猫鼬4.0更新

如评论和victorkohl的答复中所述,当您在2941972379263828828调用中包含2941972379263828828994选项时,猫鼬现在支持$set$unset运算符字段的验证。

JohnnyHK answered 2020-06-27T21:22:17Z
3 votes

mongodb默认情况下不对更新运行验证。为了使验证默认情况下也能在更新时生效,就在连接到mongodb之前,您只能设置全局设置,例如:

mongoose.set('runValidators', true); // here is your global setting

mongoose.connect(config.database, { useNewUrlParser: true });
mongoose.connection.once('open', () => {
    console.log('Connection has been made, start making fireworks...');
}).on('error', function (error) {
    console.log('Connection error:', error);
});

并且任何内置或自定义验证也将在更新时运行

Mohammad altenji answered 2020-06-27T21:23:33Z
0 votes

在您的模型中 Category.js文件:

const CategorySchema = mongoose.Schema({
category_name : {
type : String,
required : [true, 'Category Name Is Required !'],
trim : true,
maxlength : [30, 'Category Name Is To Long !'],
unique : true,
});
const Category = module.exports = mongoose.model("Category",CategorySchema);

在您的路线文件中:

router.put("/",(req,res,next)=>{
  Category.findOneAndUpdate(
  {_id : req.body.categoryId},
  {$set : {category_name : req.body.category_name} },
  **{runValidators: true}**, function(err,result) {
    if(err){
      if(err.code === 11000){
       var duplicateValue = err.message.match(/".*"/);
       res.status(200).json({"defaultError":duplicateValue[0]+" Is Already Exsist !"});
       }else{
         res.status(200).json({"error":err.message} || {"defaultError":'Error But Not Understood !'});
       }
    }else{
     console.log("From category.js (Route File) = "+result);
     res.status(200).json({"success":"Category Updated Successfully!!"});
    }
});
Deep Gandhi answered 2020-06-27T21:23:57Z
0 votes
exports.updateGroup = (request, response, next) => {
    const requestObj = request.body;
    var conditions = {
        _id: request.body._id,
        communityId: request.body.communityId
    };
    var newValues = {
        $set: requestObj
    };
    Group.updateOne(conditions, newValues, { ***runValidators: true*** }, (err, group) => {
        if (err) return response.json({
            message: "Updation of group failed",
            error: err,
            status: 500
        });
        response.json(group);
    });
};

您需要添加{runValidators:true}作为用于进行更新的验证的第三个参数。

Sathyapriyan C answered 2020-06-27T21:24:17Z
translate from https://stackoverflow.com:/questions/15627967/why-mongoose-doesnt-validate-on-update