获取没有任何给定类别的视频
Get videos which doesn't have any of given cateogires
我正在尝试获取所有具有这些参数的视频。但是即使我没有收到任何错误,我仍然会收到一些类别为 [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
有没有更好的方法 how write how write this query?
这是一个非常常见的 SQL 案例:"fetch a list of object which don't have a certain relation"。
在这些情况下唯一的解决办法是转换 "fetch the list of objects which are not in the list of objects with a certain relation" 中的句子。
在这种情况下,您必须提取所有未包含在具有这些类别之一的视频列表中的视频。
在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' )
转换为 ActiveRecord 你将拥有:
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
所以最后...
@excluded_categories = [15,17,26,32,35,36,37]
@videos = Video.without_categories(@excluded_categories)
P.S.
您的示例存在问题,因为它不会检索没有任何类别的视频。
我正在尝试获取所有具有这些参数的视频。但是即使我没有收到任何错误,我仍然会收到一些类别为 [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
有没有更好的方法 how write how write this query?
这是一个非常常见的 SQL 案例:"fetch a list of object which don't have a certain relation"。
在这些情况下唯一的解决办法是转换 "fetch the list of objects which are not in the list of objects with a certain relation" 中的句子。
在这种情况下,您必须提取所有未包含在具有这些类别之一的视频列表中的视频。
在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' )
转换为 ActiveRecord 你将拥有:
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
所以最后...
@excluded_categories = [15,17,26,32,35,36,37]
@videos = Video.without_categories(@excluded_categories)
P.S.
您的示例存在问题,因为它不会检索没有任何类别的视频。