我正在node.js(使用Express和Mongodb(带有Mongoose(的项目,在这里登录的用户可以在酒店添加评论。但是,我不希望用户添加用户对酒店的不止一次评论(只能编辑或删除现有的(。
因此,我决定创建一个中间件功能,该功能将检查登录的用户ID是否与酒店的评论作者的任何ID匹配。如果为true,我会将用户重新定向(当然,添加用户已经为酒店添加了评论的闪光消息...等(。但这对我来说不是很整洁。
在酒店的模型中,我已经实施了评论属性,我只存储参考评论的ID
middleWare.noRepeat = function(req, res, next){
if(req.isAuthenticated()){
Hotel.findById(req.params.id, function(err, foundHotel){
if(err){
console.log(err);
} else{
foundHotel.reviews.forEach(function(review){
Review.findById(review, function(err, foundReview) {
if(err){
console.log(err);
} else{
if(foundReview.author.id.equals(req.user._id)){
res.redirect("back");
//flash message to be implemented
} else {
next();
}
}
});
});
}
});
}
};
此代码对我来说效果不佳。我遇到了一个错误,说"无法阅读null的作者属性"。我认为这部分在这里:
foundHotel.reviews.forEach(function(review){
Review.findById(review, function(err, foundReview) {
可能是一个问题。我正在使用评论作为 findbyid 方法的ID参数,因为在酒店的模型中,我提到的是评论属性,该属性是存储相关评论ID的数组。看起来像这样:
reviews: [ ObjectId("53f3ada529cb20192ra35c8h"),
ObjectId("12f3d6afdcd3cd15ktbcf8e98i"),
ObjectId("1234abcdef56ghijk")]
最后,我只有2.5个月的经验才是初学者。这是我的第一个项目,如果这个问题对您来说很愚蠢,我感到很抱歉。预先感谢您!
嵌套异步调用, Hotel.findById()
&Review.findById()
,在这里可能会引起问题。如果您开放,请让我建议您使用猫鼬居民的替代方法。我认为您的酒店模式看起来像这样:
{
// some properties
reviews: [Schema.Types.ObjectId]
}
您可以更改酒店模式以看起来像这样:
{
// some properties
reviews: [{
type: Schema.Types.ObjectId,
ref: 'review' //refer your review schema here
}]
}
这样做的好处是:您可以通过ID和填充评论找到酒店,完全避免Review.findById()
。
,您的中间件应该看起来像这样:
middleWare.noRepeat = function(req, res, next){
if(req.isAuthenticated()){
Hotel
.findById(req.params.id)
.populate('reviews')
.exec(function(err, foundHotel){
if(err){
console.log(err);
} else{
foundHotel.reviews.forEach(function(review){
// this time the review variable
// will contain complete review object,
// rather than containing only id
if(review.author.id.equals(req.user._id)){
return res.redirect("back");
//flash message to be implemented
}
});
return next();
}
});
}
};
希望答案对您有帮助!