如何在Sequelize模型上实现“回复”和“回复”关联

我有一个模式在sequelize的职位。 我希望你可以检索对post的回复,以及post作为回复的post。

理论上这只需要一个外键,一个“replyId”字段,所以你有这个表格:

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

所以要获得post回复1 ,你需要查找1 replyId
并得到什么后3回复,你看id1

序列化关系是:

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

然后当添加post到数据库:

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

但是无论我尝试有什么样的错误,例如在上面的表中,它是null你得到ID 3和sequelize不会返回任何答复ID 2

发生此问题的原因是您要在单个字段replyId上保存两个关联( hasManyhasOne )。 我build议你只使用单个关联,而第二个可以通过instanceMethods轻松实现。 让我告诉你如何做到这一点

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

它在字段replyId上创build了一个关联,所以我们现在可以轻松地获取/设置指定的post的回复。 现在,为了获得在单个post上设置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; 

另一方面,我们也可以得到邮寄回复的post

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

其中生成以下SQL

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