gpt4 book ai didi

ruby-on-rails - 通过 2 个不同的关联模型进行 Rails 查询

转载 作者:行者123 更新时间:2023-11-29 13:29:19 25 4
gpt4 key购买 nike

我在尝试让查询按我想要的方式工作时遇到了一些麻烦,我没有得到我希望的所有结果。

我有 3 个模型 PostCommentTag。帖子和评论都可以包含标签,并且都与标签有 has_and_belongs_to_many 关系。我希望能够获得所有具有指定标签或带有该标签的评论的帖子,我一直在以下范围内对这样的帖子进行操作:

scope :tag, -> (tag_id) { joins(:tags, :comment_tags).where("tags_posts.tag_id = :tag_id OR comments_tags.tag_id = :tag_id", tag_id: tag_id) }

但这并没有返回所有的帖子,只是其中的一个子集,似乎它只是关于评论的,这是它生成的查询:

SELECT COUNT(*) FROM "posts" 
INNER JOIN "tags_posts" ON "tags_posts"."post_id" = "posts"."id"
INNER JOIN "tags" ON "tags"."id" = "tags_posts"."tag_id"
INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
INNER JOIN "comments_tags" ON "comments_tags"."comment_id" = "comments"."id"
INNER JOIN "tags" "comment_tags_posts" ON "comment_tags_posts"."id" = "comments_tags"."tag_id"
WHERE (tags_posts.tag_id = 1 OR comments_tags.tag_id = 1)

这些是模型:

class Post < ActiveRecord::Base
has_and_belongs_to_many :tags
has_many :comment_tags, through: :comments, source: :tags
end

class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts
has_and_belongs_to_many :comments
end

class Comment < ActiveRecord::Base
belongs_to :post
has_and_belongs_to_many :tags
end

最佳答案

我不确定您是否已经解决了这个问题,但如果您还没有解决,这里有一个可能的解决方案:

在纯 SQL 中,主要用于说明目的:

SELECT 
DISTINCT posts.*
FROM
posts
INNER JOIN
tags_posts ON tags_posts.post_id = posts.id
LEFT JOIN
comments ON comments.post_id = posts.id
LEFT JOIN
comments_tags ON comments_tags.comment_id = comments.id
INNER JOIN
tags ON (tags.id = tags_posts.tag_id OR tags.id = comments_tags.tag_id)
WHERE tags.id = 1

原始版本中的主要问题是您使用commentscomments_tags 进行INNER JOIN。结果,您可能删除了所有没有任何评论的 Post。所以解决方案是 LEFT JOIN 与评论相关的所有内容。然后,因为我们要加入,所以我们可以在标签帖子或评论帖子上INNER JOIN tags

转换为 Active Record 不是很好,但有必要:

Post.joins("INNER JOIN posts_tags ON posts_tags.post_id = posts.id")
.joins("LEFT JOIN comments ON comments.post_id = posts.id")
.joins("LEFT JOIN comments_tags ON comments_tags.comment_id = comments.id")
.joins("INNER JOIN tags ON (posts_tags.tag_id = tags.id OR comments_tags.tag_id = tags.id)")
.where(tags: {id: 1})
.uniq

请注意 DISTINCTuniq 的必要性,因为 LEFT JOIN 会导致重复。

编辑

如果对数据集或结构有一些误解,这是我在测试中用于创建上述查询的数据示例。

帖子

+----+--------------------------+
| id | text |
+----+--------------------------+
| 1 | Post about programming 1 |
| 2 | Post about programming 2 |
| 3 | Post about programming 3 |
| 4 | Post about cooking 1 |
| 5 | Post about cooking 2 |
+----+--------------------------+

标签

+----+-------------+
| id | name |
+----+-------------+
| 1 | programming |
| 2 | cooking |
| 3 | woodworking |
+----+-------------+

tags_posts

+--------+---------+
| tag_id | post_id |
+--------+---------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 4 |
| 2 | 5 |
+--------+---------+

评论

+----+----------------------------------------------+---------+
| id | comment_text | post_id |
+----+----------------------------------------------+---------+
| 1 | comment - programming on programming post 1a | 1 |
| 2 | comment - programming on programming post 1b | 1 |
| 3 | comment - programming on programming post 2a | 2 |
| 4 | comment - cooking on programming post 3a | 3 |
| 5 | comment - programming on cooking post 4a | 4 |
| 6 | comment - cooking on cooking post 4b | 4 |
| 7 | comment - cooking on cooking post 5a | 5 |
+----+----------------------------------------------+---------+

评论标签

+--------+------------+
| tag_id | comment_id |
+--------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 5 |
| 2 | 4 |
| 2 | 6 |
| 2 | 7 |
+--------+------------+

如果我想搜索“programming”,上面的查询将产生这个结果集:

+----+--------------------------+
| id | text |
+----+--------------------------+
| 1 | Post about programming 1 |
| 2 | Post about programming 2 |
| 4 | Post about cooking 1 |
| 3 | Post about programming 3 |
+----+--------------------------+

因为我们有 3 个帖子专门标记为“编程”,并且在一个不同标记的帖子上有一个评论标记为“编程”。

关于ruby-on-rails - 通过 2 个不同的关联模型进行 Rails 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27430852/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com