【问题标题】:Mongoose not updating database with findByIdAndUpdate?Mongoose 不使用 findByIdAndUpdate 更新数据库?
【发布时间】:2020-08-12 14:40:17
【问题描述】:

我正在尝试通过 HTML 表单使用 findByIdAndUpdate 更新我的数据库,该表单适用于除嵌套数据之外的所有数据(ePIMScodeVersionregion 都可以正常更新)。当我执行console.log(req.body.environment.instance) 时,它会输出我输入的数据,就像它正确通过一样,但由于某种原因,mongoDB 没有更新信息。谁能弄清楚我做错了什么?

猫鼬模式:

var environmentSchema = new mongoose.Schema({
    ePIMS: String,
    codeVersion: String,
    region: String,
    /*instance and testEnv don't seem to update in the database*/
    HCHC: {
      instance: String,
      testEnv: String
    }
  });

我用来更新的表格:

    <form action="/environments/<%= environment._id %>?_method=PUT" method="POST">
        <input class="form-control" type="text" name="environment[ePIMS]" placeholder="ePIMS" value="<%= environment.ePIMS %>" />
        <input class="form-control" type="text" name="environment[region]" placeholder="Region" value="<%= environment.region %>" />

        <input class="form-control" type="text" name="environment[instance]" placeholder="HCHC Instance" value="<%= environment.instance %>" />
        <input class="form-control" type="text" name="environment[testEnv]" placeholder="Test Environment" value="<%= environment.testEnv %>" />
        <button class="btn btn-primary">Submit</button>
    </form>

编辑和更新路线:

//Edit environment route
  router.get("/environments/:id/edit", function(req, res){
      Environment.findById(req.params.id, function(err, foundEnvironment){
          if(err){
              res.redirect("/");
          } else {
              res.render("edit", {environment: foundEnvironment});
          }
      });
  });

  //Update environment route
router.put("/environments/:id", function(req, res){
  Environment.findByIdAndUpdate(req.params.id, req.body.environment, function(err, updatedEnvironment){
    if (err) {
      res.redirect("/environments");
    } else {
      res.redirect("/environments");
      //console.log(req.body.environment.instance)
    }
  });
});

更新:解决方案 感谢 Nayan 的帮助!

我像这样更改了更新路线:

 //Update environment route
router.put("/environments/:id", function(req, res){
  var data = {
    HCHC : {
      instance: req.body.instance,
      testEnv: req.body.testEnv
    }
  }
  Environment.findByIdAndUpdate(req.params.id, {$set: data}, function(err, updatedEnvironment){
    if (err) {
      res.redirect("/environments");
    } else {
      res.redirect("/environments");
    }
  });
});

【问题讨论】:

  • req.params.id 以字符串形式出现,而数据库中的 _id 可能是 ObjectId。你可以试试:mongoose.Types.ObjectId(req.params.id) 吗?
  • @mickl 你的意思是 console.log 还是尝试用它代替 req.params.id
  • 尝试替换req.params.id将值转换为ObjectId
  • @mickl 嗯,这似乎没有任何改变:/

标签: javascript html node.js mongodb mongoose


【解决方案1】:

您正在发送不同的正文结构并直接在 findOneAndUpdate() 中设置它,所以它不起作用,结构不同。

您可以应用的可能解决方案是将请求的正文更改为如下所示:

"environment" : {
    "ePIMS" : value,
    "codeVersion" : value,
    "region" : value,
    "HCHC": {
        "instance" : value,
        "testEnv" : value
    }
}

或者如果你愿意,你可以把两个事物实例和 testEnv 放在 HCHC 之外。

如果您直接在函数中传递正文,请确保您具有相同的结构。

另一种解决方案

创建一个局部变量来修复结构并将其传递给函数,例如:

router.put("/environments/:id", function(req, res){
  let body = req.body.environment
  let bodyData = {
    ePIMS: body.ePIMS,
    codeVersion: body.codeVersion,
    region: body.region,
    HCHC: {
      instance: body.instance,
      testEnv: body.testEnv
    }
  }
  Environment.findByIdAndUpdate(req.params.id, bodyData, function(err, updatedEnvironment){
    if (err) {
      res.redirect("/environments");
    } else {
      res.redirect("/environments");
      //console.log(req.body.environment.instance)
    }
  });
});

【讨论】:

  • 谢谢!!!根据您的建议,我已经用解决方案编辑了我的问题
  • 很高兴为您提供帮助...您可以探索解构以使其更清洁 - reference.
【解决方案2】:

这个解决方案对我有用:

router.patch('/tasks/:id', async (req,res)=>{



    try{
        const task= await Task.findByIdAndUpdate(req.params.id,req.body,{new:true,runValidators:true})

        if(!task)
        {
            res.status(404).send()
        }
    res.send(task)    
    }
    catch(e)
    {
        res.status(500).send()
    }
})

但是,我的最终解决方案包括验证是在不使用 findByIdAndUpdate 的情况下实现更新:

router.patch('/tasks/:id', async (req,res)=>{ 
//validate update operation  


const updates=Object.keys(req.body)
  const allowedUpdates= ['description','completed']
  const isInvalidOperation= updates.every((update)=>allowedUpdates.includes(update))




  if(!isInvalidOperation)
  {
     return res.status(400).send({error:'invalid updates'})
  }


  try{
      const task= await Task.findById(req.params.id)
      updates.forEach((update)=>task[update]=req.body[update])
      await task.save()

      if(!task)
      {
          res.status(404).send()
          }
      res.send(task)    
      }
      catch(e)
      {
          res.status(500).send()
      }
  })

【讨论】:

  • 谢谢!我得到了它的工作,但非常感谢你的帮助!
猜你喜欢
  • 2021-10-23
  • 1970-01-01
  • 2014-02-19
  • 2021-01-28
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 2018-11-25
相关资源
最近更新 更多