如何在 Sequelize 模型上实现 'replyingTo' 和 'replies' 关联
How to implement 'replyingTo' and 'replies' associations on Sequelize model
我有一个模型正在为 post 续集。我希望您可以检索 到 和 post 的回复,以及 post 和 post 的回复。
理论上这只需要一个外键,一个 'replyId' 字段,所以你有 table:
----------------------
|id|post |replyId|
----------------------
|1 |post one |null |
|2 |replying |1 |
|3 |replying |1 |
----------------------
因此,要让 post 回复 1
,您需要查找 1
、
中的 replyId
要获得 post 3
的回复,您需要查找 1
的 id
续集关系为:
Post.hasMany(models.Post, { as: 'Replies' })
Post.hasOne(models.Post, { as: 'ReplyingTo' })
然后在将 posts 添加到数据库时:
//Having created `post`
post.setReplyingTo(replyingToPost)
//Having found `replyingToPost`
replyingToPost.addReplies(post)
但无论我尝试什么,都存在某种错误,例如在上面的 table 中,它是 null
你得到 id 3
而 sequelize 没有 return id 2
的任何回复
出现此问题是因为您想在单个字段 replyId
上持有两个关联(hasMany
和 hasOne
)。我建议你只使用一个关联,第二个可以通过 instanceMethods
轻松实现。让我告诉你如何做到这一点
Post.hasMany(models.Post, { as: 'Replies', foreignKey: 'replyId' });
它在字段 replyId
上创建一个关联,因此我们现在可以轻松 get/set 指定 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回复
的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;
我有一个模型正在为 post 续集。我希望您可以检索 到 和 post 的回复,以及 post 和 post 的回复。
理论上这只需要一个外键,一个 'replyId' 字段,所以你有 table:
----------------------
|id|post |replyId|
----------------------
|1 |post one |null |
|2 |replying |1 |
|3 |replying |1 |
----------------------
因此,要让 post 回复 1
,您需要查找 1
、
中的 replyId
要获得 post 3
的回复,您需要查找 1
id
续集关系为:
Post.hasMany(models.Post, { as: 'Replies' })
Post.hasOne(models.Post, { as: 'ReplyingTo' })
然后在将 posts 添加到数据库时:
//Having created `post`
post.setReplyingTo(replyingToPost)
//Having found `replyingToPost`
replyingToPost.addReplies(post)
但无论我尝试什么,都存在某种错误,例如在上面的 table 中,它是 null
你得到 id 3
而 sequelize 没有 return id 2
出现此问题是因为您想在单个字段 replyId
上持有两个关联(hasMany
和 hasOne
)。我建议你只使用一个关联,第二个可以通过 instanceMethods
轻松实现。让我告诉你如何做到这一点
Post.hasMany(models.Post, { as: 'Replies', foreignKey: 'replyId' });
它在字段 replyId
上创建一个关联,因此我们现在可以轻松 get/set 指定 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回复
的postfirstReply.getReplyingTo().then((replyingToPost) => {
// here we get the first created post
});
生成下面SQL
SELECT "id", "post", "replyId" FROM "posts" AS "post" WHERE "post"."id" = 1;