如何在Rails和Postgresql中查找标记有多个标记的post
我有模型Post
, Tag
和PostTag
。 post通过post标签有很多标签。 我想找到专门标记有多个标签的post。
has_many :post_tags has_many :tags, through: :post_tags
例如,给定此数据集:
posts table -------------------- id | title | -------------------- 1 | Carb overload | 2 | Heart burn | 3 | Nice n Light | tags table ------------- id | name | ------------- 1 | tomato | 2 | potato | 3 | basil | 4 | rice | post_tags table ----------------------- id | post_id | tag_id | ----------------------- 1 | 1 | 1 | 2 | 1 | 2 | 3 | 2 | 1 | 4 | 2 | 3 | 5 | 3 | 1 |
我想找到标有tomato
和basil
post。 这应该只返回“心脏燃烧”post(id 2)。 同样,如果我查询用tomato
和potato
标记的post,它应该返回“Carb overload”post(id 1)。
我尝试了以下方法:
Post.joins(:tags).where(tags: { name: ['basil', 'tomato'] })
SQL
SELECT "posts".* FROM "posts" INNER JOIN "post_tags" ON "post_tags"."post_id" = "posts"."id" INNER JOIN "tags" ON "tags"."id" = "post_tags"."tag_id" WHERE "tags"."name" IN ('basil', 'tomato')
这将返回所有三个post,因为所有post都共享标签tomato。 我也试过这个:
Post.joins(:tags).where(tags: { name 'basil' }).where(tags: { name 'tomato' })
SQL
SELECT "posts".* FROM "posts" INNER JOIN "post_tags" ON "post_tags"."post_id" = "posts"."id" INNER JOIN "tags" ON "tags"."id" = "post_tags"."tag_id" WHERE "tags"."name" = 'basil' AND "tags"."name" = 'tomato'
这不返回任何记录。
如何查询标记有多个标签的post?
您可能希望在此答案中查看编写此类查询的可能方法, 以便将条件应用于连接中的多个行 。 这是使用1B,子查询方法在Rails中实现查询的一种可能选项…
在PostTag
模型中定义一个查询,该查询将获取给定Tag
名称的Post
ID值:
# PostTag.rb def self.post_ids_for_tag(tag_name) joins(:tag).where(tags: { name: tag_name }).select(:post_id) end
在Post
模型中定义一个查询,该查询将使用子查询结构获取给定Tag
名称的Post
记录:
# Post.rb def self.for_tag(tag_name) where("id IN (#{PostTag.post_ids_for_tag(tag_name).to_sql})") end
然后你可以使用这样的查询:
Post.for_tag("basil").for_tag("tomato")
使用方法。包括,像这样:
Item.where(xpto: "test") .includes({:orders =>[:suppliers, :agents]}, :manufacturers)
文档到.includes
here 。