获取没有任何给定类别的视频

Get videos which doesn't have any of given cateogires

我正在尝试获取所有具有这些参数的视频。但是即使我没有收到任何错误,我仍然会收到一些类别为 [17] 的视频。

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.

您的示例存在问题,因为它不会检索没有任何类别的视频。