2017-03-01 35 views
2

我有一個帖子的續集模型。我希望您可以檢索回覆的帖子,以及帖子作爲回覆的帖子。如何在Sequelize模型上實現'replyingTo'和'回覆'關聯

理論上,這只是需要一個外鍵,一個「replyId」字段,所以你有表:

---------------------- 
|id|post  |replyId| 
---------------------- 
|1 |post one |null | 
|2 |replying |1  | 
|3 |replying |1  | 
---------------------- 

所以得到的帖子回覆1,你看的1replyId
和得到什麼張貼3的回答,你看的1

id的sequelize關係是:

Post.hasMany(models.Post, { as: 'Replies' }) 
Post.hasOne(models.Post, { as: 'ReplyingTo' }) 

然後添加帖子到數據庫時:

//Having created `post` 
post.setReplyingTo(replyingToPost) 
//Having found `replyingToPost` 
replyingToPost.addReplies(post) 

但無論我嘗試有一些類型的錯誤,例如像在上面的表,它是null你ID 3和sequelize沒有按「T返回任何回覆的ID 2

回答

2

出現問題的原因要在單場replyId容納兩個協會(hasManyhasOne)。我建議你只使用單個關聯,而第二個可以通過instanceMethods輕鬆實現。讓我來告訴你如何可以做到

Post.hasMany(models.Post, { as: 'Replies', foreignKey: 'replyId' }); 

它創建領域replyId一個關聯,所以我們現在就可以輕鬆搞定/指定崗位設置的答覆。現在,爲了獲得在單個帖子上設置ReplyingTo的可能性,我們將不得不在Post模型上添加兩個實例方法。

instanceMethods: { 
    getReplyingTo: function(){ 
     return this.sequelize.models.Post.findByPrimary(this.replyId); 
    }, 
    setReplyingTo: function(replyingToPost){ 
     return this.update({ replyId: replyingToPost.id }); 
    } 
} 

所以,完整的例子可能是這樣的

Post.create({ post: 'post content' }).then((post) => { 
    Post.create({ post: 'reply to previous' }).then((firstReply) => { 
     firstReply.setReplyingTo(post).then((self) => { 
      // now firstReply has replyId: 1 
     }); 
    }); 
}); 

通過setReplyingTo生成的查詢會是這樣的

UPDATE "posts" SET "replyId" = 1 WHERE "id" = 2; 

在另一方面,我們也可以得到這個職位給哪篇回覆

firstReply.getReplyingTo().then((replyingToPost) => { 
    // here we get the first created post 
}); 

其中產生以下SQL

SELECT "id", "post", "replyId" FROM "posts" AS "post" WHERE "post"."id" = 1; 
+0

感謝這工作完美!我猜這不太符合sequelize的精神,但我直接用replyingTo用戶名爲模型添加了一個字段,所以你不必每次都運行getReplyingTo() – user2521439