ruby-on-rails - ActiveRecord 在 has_and_belongs_to_many 关系上使用 AND 而不是 OR 查询多个
问题描述
我正在尝试设置对我的 Rails 应用程序的搜索。
有 2 个模型具有 has_and_belongs_to_many 关系:
class Post
has_and_belongs_to_many :tags
end
class Tag
has_and_belongs_to_many :post
end
为了确认,这里是表格:
create_table "posts" do |t|
t.bigint "user_id"
t.string "title"
...
end
create_table "tags" do |t|
t.string "name"
end
create_table "tags_posts", id: false do |t|
t.bigint "post_id", null: false
t.bigint "tag_id", null: false
t.index ["post_id", "tag_id"]
t.index ["tag_id", "post_id"]
end
我想做一个 AND 查询:All POSTS that have TAGS 1, 2, AND 3
。
我得到的最接近的是这个简单的查询,但它返回OR
而不是AND
- 所有具有这 3 个标签中的 1 个的帖子。
Post.includes(:tags).where(tags: { id: [1, 2, 3] })
.
如何获得这样的查询,在哪里可以轻松地将 N 个标签 ID 添加到 ActiveRecord 查询并使其成为AND
查询。
额外的问题 - 有没有办法添加一个参数,它返回帖子上至少存在 M 个标签的帖子。那么ALL POSTS that have AT LEAST 2 TAGS of 1, 2, AND 3
?
更新
我发现了这个:https ://stackoverflow.com/a/7994175/659820
翻译:
Post.find_by_sql("
SELECT p.* FROM posts p,
post_tags pt1,
post_tags pt2,
tags t1,
tags t2
WHERE
p.id = pt1.post_id
AND t1.id = 4
AND t1.id = pt1.post_tag_id
AND p.id = pt2.post_id
AND t2.id = 11
AND t2.id = pt2.post_tag_id
")
- 这是实现这一目标的最有效方法吗?
- 奖金问题仍未得到解答 - 为提供的 N 个标签提供一些 M 匹配项?
解决方案
您可以通过使用连接表来解决此问题。为了使用连接表获取正确的帖子,我们需要查看匹配条件的帖子的数量:
tag_ids = [1, 2, 3] # You can use tag name instead of id
Post.joins(:tags).where(tags: { id: tag_ids }).group(:id).having("count(*) = ?", tag_ids.size)
更新
这应该有效:
class Post < ApplicationRecord
def self.tagged_with(post_tags, m = nil)
m ||= post_tags.size
Post.joins(:tags).where(tags: { id: post_tags }).group(:id).having("count(*) >= ?", m)
end
end
tag_ids = [1, 2, 3]
Post.tagged_with(tag_ids)
#=> Returns posts which has all tags.
Post.tagged_with(tag_ids, 2)
#=> Returns posts which has at least two of given tags.
推荐阅读
- sql - 为什么 SQL Server 将 SS 视为 Umlaut-S (ß)?
- java - NetBeans + Glassfish --> NoSuchMethodError directExecutor()Ljava/util/concurrent/Executor
- spring-boot - Spring Cloud Stream:处理消息需要很长时间时对StreamListener的正确处理
- django - 如何在 django 的一个地方存储多个 python gui 工具?
- android - 在nestedscrollview滚动问题内的片段中的Recyclerview
- linux - 在 shell 中使用 perl -e 命令时引用问题
- python - SQLAlchemy 经典映射器自定义数据类型,来自列的 dict
- android - React Native 分享文章和视频
- javascript - 请求错误:没有为该请求指定连接;使用 express.js 连接到 Sql 服务器时?
- nginx - PHP分页的NGINX重写规则