我有两个模型,两个模型都具有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})
上面的示例查找任何恐怖或喜剧电影。
答案 0 :(得分:1)
通过将joins
与group
和having
结合使用来解决这个问题。
ids = params[:genres]
Movie.joins(:genres)
.where(genres: {id: ids})
.group(:id)
.having("count(*) = #{ids.count}")
这基本上将过滤掉重复的匹配项,并仅返回结果与原始数组计数相同的电影。这意味着,如果数组计数为3,则只有具有原始joins
查询的3个结果的电影才会匹配。