找到具有多个ID(含)的has_and_belongs_to_many关联

时间:2018-10-31 14:34:59

标签: ruby-on-rails postgresql activerecord ruby-on-rails-5

我有一个在标签上具有has_and_belongs_to_many关系的生产模型。

我有一个tag_ids = ['tag_one','tag_two']数组,我想找到具有这两个或更多标签的Productions。

示例:将返回带有标签['tag_one','tag_two','tag_three']的生产,但不会返回带有标签['tag_one','tag_three']的生产。

到目前为止我已经尝试过:

Production.includes(:tags).where(tags: { id: ['tag_one','tag_two'] })

此请求不包括在内,返回的是具有tag_one OR tag_two

的产品
Production.includes(:tags).where(tags: { id: ['tag_one'] }).where(tags: { id: ['tag_two'] })

这是一个空数组,我想它是在寻找同时具有两个ID的标记。

如果你们对我该如何解决有任何想法,那将很棒

谢谢

1 个答案:

答案 0 :(得分:1)

includes方法用于在最终结果集中包含相关记录。在这里,您需要使用关联对象过滤记录,这可以通过joins完成。

然后,应将记录分组(按id)。由于连接了tags表,因此对于productions表的每条记录,您可以拥有记录标签的完整列表。根据您的情况,您可以在该标签列表上应用不同的条件。

要获取Production条仅具有给定标签且没有其他内容的记录(即,带有['tag_one']['tag_one', 'tag_two', 'tag_three']的记录将被忽略):

Production.joins(:tags)
          .having("array_agg(tags.id ORDER BY tags.id ASC) = ARRAY[#{tag_ids.sort.map { |t| "'#{t}'" }.join(',')}]")
          .group('productions.id')

要获取具有每个给定标签的Production条记录(即也将提取带有['tag_one', 'tag_two', 'tag_three']标签的记录)

Production.joins(:tags)
          .where(tags: { id: tag_ids })
          .having("count(*) = #{tag_ids.count}")
          .group('productions.id')