Rails:返回不存在关系的记录

时间:2011-01-24 20:40:25

标签: ruby-on-rails activerecord

使用有效记录,如果模型的结果存在于其他地方的特定关系中,我该如何返回结果。例如,假设我有Recipe模型属于categories(通过category_recipes联接表)。

所以基本上我有一个Rake任务,可以查看每个食谱及其描述,并尝试输入一个类别,但任务需要很长时间,我需要定期运行它,所以我只想要运行它,如果有问题的Recipe尚未被分类,我宁愿不添加像categorized这样多余的列,所以我认为有一种方法可以只检索不需要的食谱t存在于连接表中。有什么想法吗?

5 个答案:

答案 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')