You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose关联存储异常:评论对象存入营地数组而非ObjectId求助

Fixing Comment-Campground Association Sync Issue in Mongoose

Hey there! I can spot exactly what's throwing your data sync off—you're pushing the full comment object into the campground's comments array instead of just its ObjectId. Let's get this fixed so your updates and deletions work across both collections.

The Root Problem

Your Campground schema clearly defines the comments field as an array of ObjectIds that reference the Comment model:

comments: [ { type: mongoose.Schema.Types.ObjectId, ref: "Comment" } ]

But in your POST route, you're pushing the entire createdComment document into this array:

foundCampground.comments.push(createdComment);

Mongoose doesn't automatically extract the ObjectId from the full object here, so it stores the entire comment instead of just the reference ID. That's why changes to comments only affect the Comment collection, not the linked Campground data.

The Simple Fix

Instead of pushing the whole comment object, push only its _id property. Here's the corrected POST route code:

router.post("/", middleware.isLoggedIn, function(req, res) {
  Comment.create(req.body.comment, function(err, createdComment) {
    if(err) {
      console.log(err);
      req.flash("error", "Failed to create comment");
      return res.redirect("back");
    }
    // Set author info and save the comment
    createdComment.author.id = req.user._id;
    createdComment.author.username = req.user.username;
    createdComment.save(function(err) {
      if(err) {
        console.log(err);
        return res.redirect("back");
      }
      // Find the campground and add ONLY the comment's ObjectId
      Campground.findById(req.params.id, function(err, foundCampground){
        if(err) {
          console.log(err);
          req.flash("error", "Could not find campground");
          return res.redirect("back");
        }
        foundCampground.comments.push(createdComment._id);
        foundCampground.save(function(err) {
          if(err) {
            console.log(err);
          } else {
            req.flash("success" , "Comment created successfully");
            res.redirect("/index/" + req.params.id);
          }
        });
      });
    });
  });
});

Key Adjustments:

  • Removed unnecessary .populate("comments") from the Campground lookup—you don't need to load all comments just to add a new reference ID
  • Changed foundCampground.comments.push(createdComment) to foundCampground.comments.push(createdComment._id)
  • Added extra error handling to catch issues at each step (always saves headaches later!)

Bonus: Syncing Comment Deletions

Now that your associations use ObjectIds, you'll want to update the campground when a comment is deleted. Add this logic to your comment deletion route using Mongoose's $pull operator to remove the reference ID:

router.delete("/:commentId", middleware.checkCommentOwnership, function(req, res) {
  // Delete the comment from the Comment collection
  Comment.findByIdAndRemove(req.params.commentId, function(err) {
    if(err) {
      req.flash("error", "Failed to delete comment");
      return res.redirect("back");
    }
    // Remove the comment's ID from the campground's comments array
    Campground.findByIdAndUpdate(
      req.params.id,
      { $pull: { comments: req.params.commentId } },
      function(err) {
        if(err) {
          console.log(err);
        }
        req.flash("success", "Comment deleted");
        res.redirect("/index/" + req.params.id);
      }
    );
  });
});

This ensures deleting a comment removes it from both collections, keeping your data perfectly in sync.

内容的提问来源于stack exchange,提问作者Blackdeath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:31:03