我想向博客Web应用程序添加评论功能。我目前有一篇文章,或者我称之为“采访”模式,如下所示:

var InterviewSchema = new mongoose.Schema({
  slug: {type: String, lowercase: true, unique:true},
  title: String,
  description: String,
  body: String,
  favoritesCount: {type: Number, default: 0},
  tagList: [{type: String}],
  author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
  comments: [{type: mongoose.Schema.Types.ObjectId, ref: 'Comment'}]
}, {timestamps: true, usePushEach: true});


它包含一个注释数组,该注释引用了我创建的注释模型:

var CommentSchema = new mongoose.Schema({
  body: String,
  author: {type: mongoose.Schema.Types.ObjectId, ref:'User'},
  interview: {type: mongoose.Schema.Types.ObjectId, ref:'Interview'}
}, {timestamps: true});


在我的路由器中,我有一个post方法可以对特定文章发表评论:

router.post('/:interview/comments', auth.required, function(req, res, next){
  User.findById(req.payload.id).then(function(user) {
    if(!user) {return res.sendStatus(401); }

    var comment = new Comment(req.body.comment);
    comment.interview = req.interview;
    comment.author = user;

    return comment.save().then(function() {
      req.interview.comments.push(comment);

      return req.interview.save().then(function(article) {
        res.json({comment: comment.toJSONFor(user)});
      });
    });
  }).catch(next);
});


当我在邮递员上发送此端点的请求时,收到以下错误消息:

{
    "errors": {
        "message": "Cannot read property 'push' of undefined",
        "error": {}
    }
}


在我的post方法中引用以下行:
req.interview.comments.push(comment);

我似乎无法弄清楚为什么收到此错误消息。任何建议或反馈表示赞赏!

最佳答案

产生此错误的原因是req.interview.commentsundefined。请注意,已定义req.interview,否则您将获得无法读取未定义错误的属性“注释”。

根据提供的代码,看起来您正在使用express,并且req.interview很可能是使用app.param() middleware初始化的。

请尝试在代码中找到app.param('interview', function(...)),然后仔细检查该方法如何解决采访。很可能是简单的Interview.findById调用。

在这种情况下,应通过将此行添加到中间件来解决此问题:

interview.comments = interview.comments || [];


否则,您可以修补路由处理程序:

interview.comments = interview.comments || [];
req.interview.comments.push(comment);


这应该可以解决您的问题。

中间件极有可能不是注入猫鼬模型实例,而是其他方式,在这种情况下,您将通过从db获取模型来解决问题:

Interview.findById(req.params.interview);


注意,req.params用于获取采访ID。

非常有趣的是,如何将interview.comments设置为undefined。像这样初始化面试模型时:

new Interview({ author: user, title: 'Demo Interview' }).save()


猫鼬将为注释属性创建并保留一个空数组。因此,可以使用显式设置为commentsundefined初始化并保留代码采访中的某个位置,或者通过其他方式修改您的db对象。


更新:

再次考虑,此错误的根本原因很可能是由于缺少数据库迁移。


  我想向博客Web应用程序添加评论功能。


更改模型架构时,猫鼬不会自动修补现有的数据库集合。因此,在将comments属性引入interview模型后,所有新的采访将由具有初始化的comments属性的猫鼬保留。

但是,当您访问在此更改之前创建的采访时,comments属性将丢失,从而导致此特定错误。

因此,另一个解决方案是迁移现有的db数据,例如:

db.getCollection('interviews').updateMany({ comments: null }, { $set: { comments: [] }})


这样,您的所有数据将保持一致。尽管有some tools可用于编写迁移,但对于这种特定情况,它们可能有些过大。

07-26 03:41