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

如何用Active Record查询完全不含指定食材的食谱?

查询完全不含指定食材的食谱(Active Record 实现)

直接给两种靠谱的实现方式,解决你遇到的问题:

方法1:左连接+分组统计

通过左连接保留所有食谱,再筛选出完全不包含目标食材的记录:

# 定义要排除的食材列表
excluded_ingredients = ['Cheese', 'Beef']

Recipe.left_joins(:ingredients)
      .where(ingredients: { name: excluded_ingredients })
      .group('recipes.id')
      .having('COUNT(ingredients.id) = 0')

逻辑说明:左连接会保留所有食谱(哪怕没有任何食材),然后我们筛选出关联食材是要排除的那些记录,最后分组统计关联食材的数量——数量为0就说明这个食谱完全没用到指定食材。

方法2:NOT EXISTS子查询

逻辑更直观,先找出所有包含指定食材的食谱ID,再排除这些ID:

excluded_ingredients = ['Cheese', 'Beef']

Recipe.where.not(
  id: Ingredient.where(name: excluded_ingredients).select(:recipe_id)
)

逻辑说明:子查询先拿到所有用到Cheese或Beef的食谱ID,外层查询直接排除这些ID,剩下的就是完全不含目标食材的食谱。

为啥你原来的写法会返回所有食谱?

大概率是用了内连接(joins(:ingredients))加where.not的组合——这种写法只会排除那些包含指定食材的关联行,但只要食谱有其他食材,还是会被返回;甚至连完全没有食材的食谱都会因为内连接被过滤掉,最后结果自然不对。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:30:57