1个用户可以为一个酒店/汽车旅馆/对象添加1条评论[Node.js和MongoDB]?



我正在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();
          }
      });
  }  
};

希望答案对您有帮助!

最新更新