2017-02-14 126 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); 
});