选择包含所有标签的文章(通过habtm关系)

时间:2015-05-21 14:18:03

标签: ruby-on-rails postgresql tags

我有文章模型has_and_belongs_to_many标记。

我想找到指定了标签的文章,例如tags = [" tag1," tag2"," tag" 3]

在sql查询中拥有所有内容会很好。 (使用Postgresql)

看起来使用Postgresql数组会很好。

目前,我正在研究这种方法:

select "articles".*, 
(
  select array(
    select tags.name from tags
    inner join articles_tags on articles_tags.tag_id = tags.id and articles_tags.article_id = articles.id
  )
) as tags
FROM "articles"

我试图做标签&& ARRAY [?]并传递代码,但它不起作用,因为'代码不是列'。

也许你可以推荐优雅的rails方式解决方案。

UPD

看起来这个sql需要什么,但它看起来不是很友好的Rails:

select articles.*
from articles 
where articles.id in (
  select t.id
  from (
    select articles.id, array_agg(articles_tags.tag_id) as tag_ids
    from articles
    inner join articles_tags on articles_tags.article_id = articles.id
    group by articles.id
  ) as t
  where t.tag_ids @> array[2,3]
)

有没有办法让它成为Rails方式?

谢谢!

1 个答案:

答案 0 :(得分:2)

您可以尝试这样的事情:

required_tags = ["tag1", "tag2", "tag3"]

Article.joins(:tags)
       .where(tags: { name: required_tags })
       .group('articles.id')
       .having('count(*) = ?', required_tags.count)

它的作用是:

  • 获取所有包含标签的文章
  • ,其中包含一个必需的标记
  • 对它们进行分组,这样当文章标记为“tag1”,“tag2”和“tag3”时,我们就会有一组3,或者当文章标记为“tag1”时,我们只有一组2, “tag2”和“tag4”。
  • 然后,只使用我们所需的标签数组中指定的成员数量的那些组。

可能有更好的方法来实现你想要的东西,但这是我能想到的唯一解决方案。