我正在尝试使用这些参数获取所有视频。但即使我没有得到任何错误,我仍然会得到一些类别[17]的视频。
[15,17,26,32,35,36,37]
100
Video.rb
class Video < ActiveRecord::Base
self.primary_key = "id"
has_and_belongs_to_many :categories
end
Category.rb
class Category < ActiveRecord::Base
has_and_belongs_to_many :videos
end
我的查询
@excluded_categories = [15,17,26,32,35,36,37]
@videos = Video.joins(:categories).where("duration >= 100").where.not( categories: { id: @excluded_categories } ).pluck(:video_id).uniq
有没有更好的方法来编写如何编写此查询?
答案 0 :(得分:0)
This is a very common SQL case: "fetch a list of object which don't have a certain relation".
The only solution in these cases is to transform the sentence in "fetch the list of objects which are not in the list of objects with a certain relation".
In you case you have to extract all the videos whch are not included in the list of videos with one of these categories.
In SQL:
select videos.*
from videos
where videos.id not in ( select v2.id
from videos v2
join categories_videos cv on cv.video_id == v2.id
join categories c on cv.category_id == c.id
where c.id in '15,17,26,32,35,36,37' )
Converted into ActiveRecord you will have:
class Video < ActiveRecord::Base
self.primary_key = :id
has_and_belongs_to_many :categories
scope with_categories: ->(ids) { joins(:categories).where(categories: {id: ids}) }
scope without_categories: ->(ids) { where.not(id: with_categories(ids) }
end
so in the end...
@excluded_categories = [15,17,26,32,35,36,37]
@videos = Video.without_categories(@excluded_categories)
P.S.
Your example has an issue since doesn't retrieve videos which don't have any category.