Node JS Mongoose 创建一个博客文章评论系统

14

我正在尝试使用mongoose和express构建一个带有评论系统的简单博客。这里没有创建和发布博客的问题,每篇文章都可以正确显示。但是,有一些与评论和每篇博客相关的问题。评论和博客文章之间的关系是通过在文章模式中应用mongoose.Schema.Types.ObjectId来建立的,评论已经被创建以存储评论ID数组。我认为架构结构是正确的,可能是我的路由代码存在问题,请帮助,谢谢。

    // Post Schema
    const mongoose = require('mongoose');

    const postSchema = new mongoose.Schema({
      title: {
       type: String,
       trim: true,
       required: true
     },
       text: {
       type: String,
       trim: true,
       required: true
     },
      date: {
       type: Date,
       default: Date.now
     },
      comments: [{
       type: mongoose.Schema.Types.ObjectId,
       ref: 'Comment'
      }]
    })

    postSchema.virtual('url').get(function(){
      return '/post/' + this._id
     })

    module.exports = mongoose.model('Post', postSchema); 


     // Comment Schema 
     
     const mongoose = require('mongoose');

     const commentSchema = new mongoose.Schema({
        text: {
         type: String,
         trim: true,
         required: true
        },
        date: {
         type: Date,
         default: Date.now
         }
        })

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

      // Router 

       const express = require('express');
       const Post = require('../models/post');
       const Comment = require('../models/comment');

       const router = new express.Router();


       // Get comments
       router.get('/post/:id/comment', (req, res) => {
           res.render('post-comment', {title: 'Post a comment'})
       })


       // Create and Post comments, this is where I think I made mistakes

       router.post('/post/:id/comment', async (req, res) => {
           const comment = new Comment({text: req.body.text});
           const post = await Post.findById(req.params.id);
           const savedPost = post.comments.push(comment);

           savedPost.save(function(err, results){
              if(err) {console.log(err)}
              res.render('post_details', {title: 'Post details', comments: 
               results.comments})
            } )
          })


        //  Get each post details. 
        // Trying to display comments, but it is all empty and I realized 
        // the comments array is empty, I can see the comments create in 
        // mongodb database why is that?????

       router.get('/post/:id', (req, res) => {
         Post.findById(req.params.id)
             .populate('comments')
             .exec(function(err, results) {
           if(err) {console.log(err)}
             res.render('post_details', {title: 'Post details', post: 
          results, comments: results.comments})
           })
         })

       router.get('/new', (req, res) => {
         res.render('create-post', {title: 'Create a post'})
        })

       router.post('/new', (req, res) => {
         const post = new Post({
          title: req.body.title,
          text: req.body.text
          });
          post.save(function(err) {
           if(err) {console.log(err)}
             res.redirect('/')
          })
         })

       router.get('/', (req, res) => {
          Post.find()
             .exec(function(err, results) {
              if(err) {console.log(err)}

              res.render('posts', {title: 'All Posts', posts: results})
           })
       });

      module.exports = router;
      
1个回答

27

我发布这个问题已经几天了,到目前为止还没有收到答案。但是我已经发现我的代码为什么不起作用了,并且本帖将尝试回答我几天前提出的这个问题,希望能帮助一些正在遇到同样问题的人。

我的问题在于每个创建的评论都无法推送到帖子中的评论数组中,因此数组为空时无法显示评论。

如果您查看我的架构代码,您可能会意识到我对评论架构犯了错误,因为我没有定义一个帖子键值对,因此正确的评论和帖子架构应如下所示。逻辑在于每篇博客文章下方可以有多个评论,因此应该将帖子方案中的评论创建为数组,但是每个评论只能属于其中的一个帖子,因此评论模式中的帖子键值对应该只是一个对象。

        const mongoose = require('mongoose');

        const commentSchema = new mongoose.Schema({
         text: {
              type: String,
              trim: true,
              required: true
           },
        date: {
              type: Date,
              default: Date.now
           },
       // each comment can only relates to one blog, so it's not in array
        post: {
              type: mongoose.Schema.Types.ObjectId,
              ref: 'Post'
           }
         })

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

帖子模式应该如下所示

        const mongoose = require('mongoose');

        const postSchema = new mongoose.Schema({
           title: {
             type: String,
             trim: true,
              required: true
           },
           text: {
             type: String,
             trim: true,
             required: true
           },
           date: {
             type: Date,
             default: Date.now
            },
         // a blog post can have multiple comments, so it should be in a array.
         // all comments info should be kept in this array of this blog post.
          comments: [{
             type: mongoose.Schema.Types.ObjectId,
             ref: 'Comment'
           }]
           })

           postSchema.virtual('url').get(function(){
              return '/post/' + this._id
           })

         module.exports = mongoose.model('Post', postSchema);

我没有做的另一件重要的事情是,每次有评论发布时,应该将此评论推送到post.comments数组中。 我没有执行此步骤,这就是为什么我的数组始终为空,并且没有可显示的评论。 修正此问题的代码请转到commentRouter.js文件(我已经创建了postRouter.js和commentRouter.js),添加以下代码:

         router.post('/post/:id/comment', async (req, res) => {
              // find out which post you are commenting
               const id = req.params.id;
              // get the comment text and record post id
               const comment = new Comment({
               text: req.body.comment,
               post: id
            })
              // save comment
           await comment.save();
              // get this particular post
           const postRelated = await Post.findById(id);
              // push the comment into the post.comments array
           postRelated.comments.push(comment);
              // save and redirect...
           await postRelated.save(function(err) {
           if(err) {console.log(err)}
           res.redirect('/')
           })

          })
以上是我修复错误的方法,希望能对某些人有所帮助。 感谢阅读。

感谢您提供详细的解释。我目前遇到了同样的问题。我仍在尝试将新评论添加到数据库中,但无法实现。您的评论路由路径与我的相同:“posts/:id/comment”。请问,您是如何设置app.use()的路径的?是这样的吗:app.use(/api/posts/id/comment)? - Kingsley
数组.push非常简单。谢谢。 - Ganesh MB
我有一个问题,为什么你选择了单独的评论模型,而不是将评论保留在相同的博客架构中,因为评论永远不会被单独调用。 - Pratik Solanki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接