组合作用域不起作用
Combining scopes doesn't work
我正在尝试将三个示波器合二为一(一个示波器使用另外两个)。
我想获取所有没有特定类别和特定标签的视频。
视频
class Video < ActiveRecord::Base
self.primary_key = "id"
has_and_belongs_to_many :categories
has_and_belongs_to_many :tags
scope :with_categories, ->(ids) { joins(:categories).where(categories: {id: ids}) }
scope :excluded_tags, -> { joins(:tags).where(tags: {id: 15}) }
scope :without_categories, ->(ids) { where.not(id: excluded_tags.with_categories(ids) ) }
end
但是当我打电话时
@excluded_categories = [15,17,26,32,35,36,37]
@videos = Video.without_categories(@excluded_categories)
我仍然收到带有标签 15 的视频。
服务器正在触发的 SQL 查询如下所示
SELECT "videos"."video_id" FROM "videos" WHERE ("videos"."id" NOT IN (SELECT "videos"."id" FROM "videos" INNER JOIN "tags_videos" ON "tags_videos"."video_id" = "videos"."id" INNER JOIN "tags" ON "tags"."id" = "tags_videos"."tag_id" INNER JOIN "categories_videos" ON "categories_videos"."video_id" = "videos"."id" INNER JOIN "categories" ON "categories"."id" = "categories_videos"."category_id" WHERE "tags"."id" = AND "categories"."id" IN (15, 17, 26, 32, 35, 36, 37))) [["id", 15]]
我是不是做错了什么?
scope :excluded_tags, -> { joins(:tags).where.not(tags: {id: 15}) }
scope :without_categories, ->(ids) { excluded_tags.with_categories(ids) }
我认为你必须使用一个排除类别的范围和第二个排除标签的范围,然后将它们组合起来。
scope :without_categories, ->(ids) { joins(:categories).where.not(categories: {id: ids}) }
scope :without_tags, ->(ids) { joins(:tags).where.not(tags: {id: ids}) }
那你就可以使用
@excluded_categories = [1,2,3,4]
@excluded_tags = [1,2,3,4,5,6]
@videos = Video.without_categories(@excluded_categories).without_tags(@excluded_tags)
评论后编辑
看到查询后,因为链式作用域正在使用并且生成的查询不能return所需的结果。一种新方法是仅为此目的创建一个范围。
scope :without_categories_tags, ->
(category_ids, tag_ids) { joins( :categories, :tags).
where('categories.id NOT IN (?) OR tags.id NOT IN (?)', category_ids, tag_ids)}
你可以使用
@excluded_categories = [1,2,3,4]
@excluded_tags = [1,2,3,4,5,6]
@videos = Video.without_categories_tags(@excluded_categories,@excluded_tags)
我正在尝试将三个示波器合二为一(一个示波器使用另外两个)。
我想获取所有没有特定类别和特定标签的视频。
视频
class Video < ActiveRecord::Base
self.primary_key = "id"
has_and_belongs_to_many :categories
has_and_belongs_to_many :tags
scope :with_categories, ->(ids) { joins(:categories).where(categories: {id: ids}) }
scope :excluded_tags, -> { joins(:tags).where(tags: {id: 15}) }
scope :without_categories, ->(ids) { where.not(id: excluded_tags.with_categories(ids) ) }
end
但是当我打电话时
@excluded_categories = [15,17,26,32,35,36,37]
@videos = Video.without_categories(@excluded_categories)
我仍然收到带有标签 15 的视频。
服务器正在触发的 SQL 查询如下所示
SELECT "videos"."video_id" FROM "videos" WHERE ("videos"."id" NOT IN (SELECT "videos"."id" FROM "videos" INNER JOIN "tags_videos" ON "tags_videos"."video_id" = "videos"."id" INNER JOIN "tags" ON "tags"."id" = "tags_videos"."tag_id" INNER JOIN "categories_videos" ON "categories_videos"."video_id" = "videos"."id" INNER JOIN "categories" ON "categories"."id" = "categories_videos"."category_id" WHERE "tags"."id" = AND "categories"."id" IN (15, 17, 26, 32, 35, 36, 37))) [["id", 15]]
我是不是做错了什么?
scope :excluded_tags, -> { joins(:tags).where.not(tags: {id: 15}) }
scope :without_categories, ->(ids) { excluded_tags.with_categories(ids) }
我认为你必须使用一个排除类别的范围和第二个排除标签的范围,然后将它们组合起来。
scope :without_categories, ->(ids) { joins(:categories).where.not(categories: {id: ids}) }
scope :without_tags, ->(ids) { joins(:tags).where.not(tags: {id: ids}) }
那你就可以使用
@excluded_categories = [1,2,3,4]
@excluded_tags = [1,2,3,4,5,6]
@videos = Video.without_categories(@excluded_categories).without_tags(@excluded_tags)
评论后编辑
看到查询后,因为链式作用域正在使用并且生成的查询不能return所需的结果。一种新方法是仅为此目的创建一个范围。
scope :without_categories_tags, ->
(category_ids, tag_ids) { joins( :categories, :tags).
where('categories.id NOT IN (?) OR tags.id NOT IN (?)', category_ids, tag_ids)}
你可以使用
@excluded_categories = [1,2,3,4]
@excluded_tags = [1,2,3,4,5,6]
@videos = Video.without_categories_tags(@excluded_categories,@excluded_tags)