【问题标题】:How to update a text within a nested model - MERN stack如何更新嵌套模型中的文本 - MERN 堆栈
【发布时间】:2021-10-31 10:46:24
【问题描述】:

我刚开始学习 MERN 堆栈,但在使用 Express/Node 更新模型中的文本时遇到问题。我试图寻求帮助并访问了Update a model within a model How to Nest Models within a Model 但它们并不是我想要的。

我正在使用 2 个模型,将 cmets 模型嵌入到 cat 模型中,就像这样。这是评论模型

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const commentSchema = new Schema(
  {
    user_id: { type: String, required: true },
    cat_id: { type: String, required: true },
    text: {
      type: String,
      min: [3, "Comment cannot be too short"],
    },
    email: { type: String, required: true },
  },
  { timestamps: true }
);

const Comment = mongoose.model("Comment", commentSchema);
module.exports = Comment;

这个评论模型在猫模型中

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const Comment = require("./comments.js");

const catSchema = new Schema(
  {
    name: {
      type: String,
      required: true,
      unique: true,
      min: [2, "Cat name minimum of 2 characters."],
    },
    description: { type: String, required: true },
    image: { type: String },
    gender: { type: String, required: true },
    cage: { type: String, required: true },
    adoptable: { type: String, required: true },
    comments: [Comment.schema],
  },
  { timestamps: true }
);

const Cat = mongoose.model("Cat", catSchema);
module.exports = Cat;

在我的控制器中,当我更新评论时,我也需要更新 cat 模型中的相应评论,但我无法这样做。我尝试定位特定的猫 foundCat,但我无法使用 foundCat.cmets.id(req.params.id) 访问评论

奇怪的是,当我控制台记录“foundCat.cmets.id”时,它告诉我这是一个函数?所以我不知道为什么我无法访问和更新该文本...

这是我更新评论的代码:注意!有问题的部分位于最后,查找“Cat.findOne”

// For updating comment
const updateComment = async (req, res) => {
  // if there is no req.body, return error
  if (!req.body) {
    return res.status(400).json({
      success: false,
      error: "You must provide a body to update",
    });
  }

  // req.body exists, so find the comment by id and then update
  Comment.findOne({ _id: req.params.id }, (err, comment) => {
    if (err) {
      return res.status(404).json({
        err,
        message: "Comment not found!",
      });
    }
    console.log(req.body);
    // update the comment details
    comment.text = req.body.text;
    // save the updated comment
    comment
      .save()
      .then(() => {
        // return json response if successful
        return res.status(200).json({
          success: true,
          id: comment._id,
          message: "Comment updated!",
        });
      })
      .catch((error) => {
        return res.status(404).json({
          error,
          message: "Comment not updated!",
        });
      });
    // now update the comment entry for the cat too
    Cat.findOne({ _id: comment.cat_id }, (err, foundCat) => {
      console.log("This doesnt work", foundCat.comments.id(req.params.id));
      foundCat.save((err, updatedCat) => {
        console.log(updatedCat);
      });
    });
  });
};

猫体内的 cmets 示例:

【问题讨论】:

    标签: node.js mongodb express mongoose


    【解决方案1】:

    您应该在获取评论后更新 cat 实例。

    尝试像这样更改您的代码(使用async wait):

    const updateComment = async (req, res) => {
      // if there is no req.body, return error
      if (!req.body) {
        return res.status(400).json({
          success: false,
          error: 'You must provide a body to update',
        });
      }
    
      try {
        // req.body exists, so find the comment by id and then update
        const comment = await Comment.findById(req.params.id);
        if (!comment) {
          return res.status(404).json({
            err,
            message: 'Comment not found!',
          });
        }
        // update the comment details
        comment.text = req.body.text;
        // save the updated comment
        await comment.save();
    
        // now update the comment entry for the cat too
        const cat = await Cat.findById(comment.cat_id);
        const otherCatComments = cat.comments.filter((c) => c._id !== comment._id);
        cat.comments = [...otherCatComments, comment];
    
        await cat.save();
    
        res.status(200).json({
          success: true,
          id: comment._id,
          message: 'Comment updated!',
        });
      } catch (err) {
        res.status(404).json({
          error,
          message: 'Comment not updated!',
        });
      }
    };
    

    【讨论】:

      【解决方案2】:

      卢卡,谢谢!这非常有帮助,我可以看到添加到猫评论数组中的附加评论。现在唯一的问题是cats.comment.filter 没有按预期工作,因为otherCatsComments 仍然包含所有cmets。我不得不对代码进行一些挖掘,并设法通过控制台记录 id,它返回“_id: new ObjectId("617d57719e815e39f6049452"),” 我尝试将其更改为

      const otherCatComments = cat.comments.filter((c) => c._id !== `new ObjectId("${comment._id}")`);
      const otherCatComments = cat.comments.filter((c) => c._id !== ` new ObjectId("${comment._id}")`);
      const otherCatComments = cat.comments.filter((c) => c._id !== `ObjectId("${comment._id}")`);
      

      但它们似乎都不起作用,所以我不得不进行深度调试,结果发现我的代码因某些原因而关闭!我将在此处添加它们,以防将来有人遇到此问题。 首先,我的评论 ID 与我的猫模型中的评论 ID 不同。作为参考,这是我的创建评论模型(我修改它以使用 Luca 推荐的 async/await + try/catch 块:

      const createComment = async (req, res) => {
        // if there is no req.body, return error
        if (!req.body) {
          return res.status(400).json({
            success: false,
            error: "You must provide a comment",
          });
        }
      
        try {
          // req.body exists, so make a new comment
          const comment = new Comment(req.body);
          await comment.save();
          // now add comment to cat
          Cat.findById(req.params.id, (err, foundCat) => {
            // Append the comment to the cat
            foundCat.comments.push(comment);
            foundCat.save();
          });
          // somehow, if the new comment doesn't exist, return error
          if (!comment) {
            return res.status(400).json({ success: false, error: err });
          }
      
          // success!
          res.status(201).json({
            success: true,
            id: comment._id,
            message: "Comment created!",
          });
        } catch (err) {
          return res.status(400).json({
            err,
            message: "Comment not created!",
          });
        }
      };
      

      注意我在 cat 中添加 cmets 的部分: 一开始是

      foundCat.comments.push(req.body);
      

      但这会在 cat 中生成一个与评论中的评论 id 不同的评论 id。所以 req.body 被改为comment。

      修复后,我尝试了 Luca 的原始代码,但仍然无法正常工作。我的解决方法是不使用过滤器,只需删除旧评论,然后添加新评论。 代码在这里:

      const updateComment = async (req, res) => {
        // if there is no req.body, return error
        if (!req.body) {
          return res.status(400).json({
            success: false,
            error: "You must provide a body to update",
          });
        }
      
        try {
          // req.body exists, so find the comment by id and then update
          const comment = await Comment.findById(req.params.id);
          if (!comment) {
            return res.status(404).json({
              err,
              message: "Comment not found!",
            });
          }
          // update the comment details
          comment.text = req.body.text;
          // save the updated comment
          await comment.save();
      
          // now update the comment entry for the cat too
          const cat = await Cat.findById(comment.cat_id);
          // remove the old, non-updated comment first
          cat.comments.id(comment._id).remove();
          // now add in the updated comment
          cat.comments.push(comment);
      
          await cat.save();
      
          res.status(200).json({
            success: true,
            id: comment._id,
            message: "Comment updated!",
          });
        } catch (err) {
          res.status(404).json({
            error,
            message: "Comment not updated!",
          });
        }
      };
      

      【讨论】:

        猜你喜欢
        • 2021-02-12
        • 2020-02-13
        • 2020-03-10
        • 1970-01-01
        • 1970-01-01
        • 2020-10-17
        • 1970-01-01
        • 1970-01-01
        • 2022-08-07
        相关资源
        最近更新 更多