使用有效记录,如果模型的结果不存在于其他地方的特定关系中,我该如何返回结果。例如,假设我有Recipe
模型属于categories
(通过category_recipes
联接表)。
所以基本上我有一个Rake任务,可以查看每个食谱及其描述,并尝试输入一个类别,但任务需要很长时间,我需要定期运行它,所以我只想要运行它,如果有问题的Recipe
尚未被分类,我宁愿不添加像categorized
这样多余的列,所以我认为有一种方法可以只检索不需要的食谱t存在于连接表中。有什么想法吗?
答案 0 :(得分:14)
您可以使用LEFT OUTER JOIN
:
Recipe.joins('LEFT OUTER JOIN recipe_categories ON recipes.id = recipe_categories.recipe_id').where('recipe_categories.recipe_id IS NULL')
答案 1 :(得分:13)
今天必须自己解决这个问题,并认为这会解决问题:
Recipe.includes(:categories).where('categories.id IS NULL').references(:categories)
答案 2 :(得分:3)
您可以使用SQL select来执行此操作。
@uncategorized_recipes = Recipe.find_by_sql("select * from recipes
where id not in ( select recipe_id from category_recipes )")
确切的语法可能因数据库而异。
答案 3 :(得分:2)
您可以使用Recipe和CategoryReceipe的pluck方法执行此操作。
步骤:
r = Receipe.pluck(:id)
#provides模型中所有id的数组。例如:[1,2,3,4, 5 ...]
cr = CategoryRecipe.pluck(:recipe_id)
#provides from recipe_id列中存在的所有ID数组。
余数= r - cr
#this取两个id和recipe_id数组并计算为一个新数组。这个新数组将只包含CategoryRecipe中不存在的那些ID。
然后,您可以在此新阵列上运行操作: Recipe.where(id:remainder).count
#gives您需要更新的记录数
我更喜欢这种方法,因为你可以把它变成一个单独的函数,你可以在评估多个关联时使用它而无需重写代码。这也非常容易测试。
答案 4 :(得分:1)
我还没有测试过,但你可以试试
Recipe.joins(:categories).select('recipes.*, categories.count(*) as category_count').where(:category_count => 0).group('recipes.id')