我想向博客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.comments
是undefined
。请注意,已定义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()
猫鼬将为注释属性创建并保留一个空数组。因此,可以使用显式设置为
comments
的undefined
初始化并保留代码采访中的某个位置,或者通过其他方式修改您的db对象。更新:
再次考虑,此错误的根本原因很可能是由于缺少数据库迁移。
我想向博客Web应用程序添加评论功能。
更改模型架构时,猫鼬不会自动修补现有的数据库集合。因此,在将
comments
属性引入interview
模型后,所有新的采访将由具有初始化的comments
属性的猫鼬保留。但是,当您访问在此更改之前创建的采访时,
comments
属性将丢失,从而导致此特定错误。因此,另一个解决方案是迁移现有的db数据,例如:
db.getCollection('interviews').updateMany({ comments: null }, { $set: { comments: [] }})
这样,您的所有数据将保持一致。尽管有some tools可用于编写迁移,但对于这种特定情况,它们可能有些过大。