You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails Active Record查询:如何筛选关联全部指定分类ID的视频

解决方法

你当前的scope实现的是「匹配任意一个选中分类」的OR逻辑,要实现「同时匹配所有选中分类」的AND逻辑,推荐用分组统计+条件过滤的方案,兼容绝大多数数据库,性能表现稳定。

1. 修改video.rb中的scope代码

scope :for_categories, -> (category_ids) {
  # 选中分类为空时直接返回全量视频,避免异常查询
  return all if category_ids.blank?

  target_category_ids = category_ids.uniq
  joins(:video_categories)
    .where(video_categories: { category_id: target_category_ids })
    .group('videos.id')
    # 统计每个视频匹配到的不重复分类数,等于选中分类总数才符合要求
    .having('COUNT(DISTINCT video_categories.category_id) = ?', target_category_ids.length)
}

2. 优化控制器参数处理

表单提交多选参数时会默认带空字符串值,建议先过滤再传入scope:

def search
  # 过滤掉空值的分类ID
  cleaned_category_ids = params[:category_ids].to_a.reject(&:blank?)
  @results = Video.for_categories(cleaned_category_ids)
end

逻辑验证

以你给出的示例数据测试:
选中分类ID为[1,7]时,target_category_ids长度为2:

  • 视频A匹配到分类1、7,统计得到不重复分类数为2,符合条件
  • 视频B匹配到分类1、7,统计得到不重复分类数为2,符合条件
  • 视频C仅匹配到分类7,统计得到不重复分类数为1,不符合条件
    返回结果正好是你预期的视频A、视频B。

内容的提问来源于stack exchange,提问作者Gregory280

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:45:06