2017-02-14 87 views
0

我遵循Thinkster的MEAN堆栈教程(https://thinkster.io/tutorials/mean-stack),该教程没有说明应该如何实现删除操作。MongoDB:如何删除已删除帖子的所有评论?

目前,我有以下模式:

var PostSchema = new mongoose.Schema({ 
    title: {type: String, required: true, maxlength: 140}, 
    link: {type: String, required: true, maxlength: 300}, 
    comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }] 
}); 

var CommentSchema = new mongoose.Schema({ 
    body: {type: String, maxlength: 200, minlength: 1}, 
    post: { type: mongoose.Schema.Types.ObjectId, ref: 'Post' } 
}); 

我有一个角工厂CRUD操作。我目前删帖有以下工厂方法:

o.deletePost = function(id) { 
    return $http.delete('/posts/' + id, null, {} 
    }).success(function(res){ 
    $window.location.href = '/#/home'; 
    return res.data; 
    }); 
}; 

我的路由器删除这个样子的:

// DELETE a post 
router.delete('/posts/:post', function(req, res, next) { 
    Post.remove({_id: req.params.post}, function(err, post) { 
     if (err) 
      res.send(err); 

     res.json({ message: 'Successfully deleted' });   
    }); 
}); 

不幸的是,当我删除这样的任何相关意见的地方留在后数据库。所以,我的问题是如何删除与帖子相关的所有评论,同时删除该帖子?

我试过Google的答案,它似乎我应该以某种方式使用MongoDB的中间件。我试过了:

// Remove Post 
module.exports.removePost = function(id, callback){ 
    Post.findById(id, function (err, doc) { 
     if (err) {} 

     doc.remove(callback); 
    }) 
} 

//Remove comments related to post 
PostSchema.pre('remove', function(next) { 

    this.model('Comment').remove({ post: this._id }, next); 
}); 

但是这并没有做任何事情,因为我不知道如何从我的CRUD工厂调用它。即使我做了也不知道它是否正确。所以,任何帮助将受到欢迎。 :)

+0

你甚至没有得到'成功删除'的消息吗?你有没有试过用[Postman](https://www.getpostman.com/)进行测试? – gh0st

+0

@ gh0st我用路由器信息更新了我的问题。 – catfood

+0

@ gh0st我收到邮件,我可以删除没有问题的帖子。问题是,当我删除一篇文章时,所有相关的评论都留在数据库中“浮动”。我想删除关联的帖子时删除它们。 – catfood

回答

0

当您在Mongoose文档上调用remove()时,Mongoose中间件将自动触发。上述delete路由中的代码不会触发中间件,因为它在模型上调用remove()而不是文档(关于此here的对话)。

我认为你有所有的东西,你只需要移动它们。保持逻辑从removePost()功能和pre('remove')中间件,并纳入逻辑到您删除路线:

// DELETE a post 
router.delete('/posts/:post', function(req, res, next) { 
    Post.findById(id, function (err, post) { 
     if (err) res.send(err); 
     post.remove(function (err, doc) { 
      if (err) res.send(err); 
      res.json({ message: 'Successfully deleted' }); 
     }); 
    }) 
}); 

我的做法“删除”,虽然是不同的。我没有实际删除文档,而是将deleted字段添加到我的模式中,并在删除时将该字段更新为true。在某些情况下,实际删除文档是有意义的,但这是要记住的。

+0

感谢您的建议,但它不起作用。我只会得到一个内部服务器错误500,如果我替换我的当前router.delete。 – catfood

+0

看来我根本无法使用router.delete访问removePost方法。该方法(removePost)与我的PostSchema目前位于同一个文件中。这是它的正确位置吗? – catfood

+0

噢好吧,如果你想在另一个文件中使用它,你将不得不导入这个函数。但不是所有这些,你只需要拿掉'removePost()'函数的内核,然后从'delete'路由中调用它。 –

0

如果任何人的怀疑,究竟解决了我的问题,这里有两个不同的解决方案:

第一个工程,通过gh0st建议,正在改变我的路由器进行删除如下:

// DELETE a post 
router.delete('/posts/:post', function(req, res, next) { 
    Post.remove({_id: req.params.post}, function(err, post) { 
     if (err) {res.send(err);} 

     Comment.remove({post: req.params.post}, function(err, post) { 
     if (err) {res.send(err);}     
     }); 

     res.json({ message: 'Successfully deleted' });   
    });  
}); 

第二个也的作品,由呼啦建议,改变了我的路由器进行删除如下:

// DELETE a post 
router.delete('/posts/:post', function(req, res, next) { 

    Post.findOne({ _id: req.params.post}, function (err, post) { 
     if (err) {res.send(err);} 

     post.remove(function (err) { 
     if (err) {res.send(err);} 

     res.json({ message: 'Successfully deleted' }); 
     }); 
    }); 
}); 

,再加入预钩到m y模式文件:

// Remove comments related to a post 
PostSchema.pre('remove', function(next) { 
    this.model('Comment').remove({ post: this._id }, next); 
});