【问题标题】:findByIdAndUpdate result in an "validation failed" error when i set "runValidators" to "true"当我将“runValidators”设置为“true”时,findByIdAndUpdate 导致“验证失败”错误
【发布时间】:2021-02-01 17:13:55
【问题描述】:

我有一个带有put 请求的快速应用程序,如果我发现此电话簿中已存在此人的姓名,则更新电话簿(我正在使用具有unique: true 的“mongoose-unique-validator”验证中的选项)

但只有当我将findByIdAndUpdaterunValidators 设置为true 时,我才会遇到此put 请求的问题

这是我的代码
架构

const personSchema = new mongoose.Schema({
  name: { type: String, required: true, minlength: 3, unique: true },
  number: {
    type: String,
    required: true,
    validate: {
      validator: function (str) {
        //the function to validate the number
      },
      message: "phone number must contain at least 8 digits",
    },
  },
});
personSchema.plugin(uniqueValidator);
personSchema.set("toJSON", {
  transform: (document, returnedObject) => {
    returnedObject.id = returnedObject._id.toString();
    delete returnedObject._id;
    delete returnedObject.__v;
  },
});
const Person = mongoose.model("Person", personSchema);

put 请求

app.put("/api/persons/:id", (req, res, next) => {
  const id = req.params.id;
  console.log(id);
  const body = req.body;
  const person = {
    name: body.name,
    number: body.number,
  };
// opts is supposed to be true; and this is where i have the problem
  const opts = { runValidators: false };
  Person.findByIdAndUpdate(id, person, opts)
    .then((updatedPerson) => {
      res.json(updatedPerson);
    })
    .catch((error) => next(error));
});

错误处理程序

const errorHandler = (error, req, res, next) => {
  console.error(error.message);

  if (error.name === "CastError" && error.kind == "ObjectId") {
    return res.status(400).send({ error: "malformatted id" });
  } else if (error.name === "ValidationError") {
    return res.status(400).json({ error: error.message });
  }

  next(error);
};

app.use(errorHandler);

我得到的错误是

error: "Validation failed: name: Cannot read property 'ownerDocument' of null"

【问题讨论】:

    标签: node.js mongodb express validation mongoose


    【解决方案1】:

    @oussama ghrib 如果您不更新名称而只更新号码(如您所指示),则更新对象可以只包含电话号码,如下所示:

    
        app.put('/api/persons/:id', (req, res, next) => {
          const { number } = req.body
          Person.findByIdAndUpdate(req.params.id, { number }, {
            new: true,
            runValidators: true,
            context: 'query'
          })
            .then((updatedPeep) => {
              res.json(updatedPeep)
            })
            .catch((err) => next(err))
        })
    
    

    如果您使用的是runValidators: true,则还需要context: 'query',如下所述:https://github.com/blakehaswell/mongoose-unique-validator#find--updates findOneAndUpdate 的作用类似于 findByIdAndUpdate 用于此目的。

    【讨论】:

      【解决方案2】:

      问题在于您的使用:findByIdAndUpdate(id, update, opts)

      更新对象应该是你要更新的属性,否则它也会尝试更新id。

      解决方案:

      app.put("/api/persons/:id", (req, res, next) => {
               const { name, number } = req.body;
              
               Person.findByIdAndUpdate(req.params.id, { name, number }, opts )
                  .then((updatedPerson) => {
                    res.json(updatedPerson);
                  })
                  .catch((err) => next(err));
          }
      

      https://mongoosejs.com/docs/api/model.html#model_Model.findByIdAndUpdate

      【讨论】:

      • 但我以为我做到了;因为我有一个只有“姓名”和“号码”的“人”?
      • 您的代码有效(复制粘贴)我不知道为什么;不过谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      • 2022-12-12
      • 1970-01-01
      相关资源
      最近更新 更多