按数组中的所有ID过滤

时间:2019-05-30 18:58:59

标签: ruby-on-rails rails-activerecord

我有两个模型,两个模型都具有has_and_belongs_to_many关系。

class Movie < ApplicationRecord
  has_and_belongs_to_many :genres
end
class Genre < ApplicationRecord
  has_and_belongs_to_many :movies
end

例如,在“电影索引”页面上,我希望能够按流派进行过滤。对于过滤器表单,我有一个流派的多选框,提交时会发送一个ID数组。

如何使用Active Record查找与数组中所有ID匹配的电影,而不是与所有ID匹配的电影?例如,如果用户选择了恐怖片和喜剧片,那么它应该过滤掉既是恐怖片又是喜剧片,而不只是恐怖片或喜剧片。

ids = params[:genres]
Movie.includes(:genres).where(genres: {id: ids})

上面的示例查找任何恐怖或喜剧电影。

1 个答案:

答案 0 :(得分:1)

通过将joinsgrouphaving结合使用来解决这个问题。

ids = params[:genres]

Movie.joins(:genres)
  .where(genres: {id: ids})
  .group(:id)
  .having("count(*) = #{ids.count}")

这基本上将过滤掉重复的匹配项,并仅返回结果与原始数组计数相同的电影。这意味着,如果数组计数为3,则只有具有原始joins查询的3个结果的电影才会匹配。