使用Arel for ROR我试图根据我的类关联属性进行查询

时间:2017-09-30 03:17:41

标签: sql ruby-on-rails arel

我有一个Recipe类和一个Ingredient类,它们通过连接表RecipeIngredients与has_many连接到has_many。我正在尝试创建一些过滤器,并尝试按照它们包含的成分数量对我的食谱进行排序。我无法弄清楚正确的SQL,我也试图用Arel来找到我的答案。但是我现在会采取任何正确的方法来查询。相反,我也将尝试查询成分得到他们所处的食谱数量。

提前感谢任何人提供的任何帮助,我的查询有问题,并且今晚完全没有任何想法。感谢。

1 个答案:

答案 0 :(得分:1)

我会考虑使用Arel来解决这类问题过于复杂。 ActiveRecord本身,就是Arel之上的一层,可以非常舒服地解决这个问题。

我假设您有以下型号

class Recipe
  has_many :recipe_ingredients
  ...
end

class RecipeIngredient
  has_one: :recipe
  has_one: :ingredient
  ...
end

class Ingredient
  has_many :recipe_ingredients
  ...
end

为了获得按成分数​​量排序的食谱,您必须生成以下SQL语句:

SELECT 
  recipes.id
  ... 
  , recipes.[last_column_name]
  # optionally
  , COUNT(*) ingredients_count        
FROM
  recipes
OUTER JOIN
  recipe_ingredients
  ON
    recipe_ingredients.recipe_id = recipe.id
GROUP BY
  ingredient_count DESC

可以通过

完成
Recipe
  .joins(:recipe_ingredients)
  .group(Recipe.column_names)
  .select(Recipe.column_names, 'COUNT(*) ingredients_count')
  .order('ingredients_count DESC') # Or ASC

返回的食谱实例将按成分数排序。他们还将有一个额外的方法ingredients_count,它返回成分的数量。

这也可以放在Recipe类的范围内。

def self.ordered_by_ingredients_count
  joins(:recipe_ingredients)
  .group(column_names)
  .select(column_names, 'COUNT(*) ingredients_count')
  .order('ingredients_count DESC') # Or ASC
end

相反,一种成分的食谱数量,只需交换一些名称:

Ingredient
  .joins(:recipe_ingredients)
  .group(Ingredient.column_names)
  .select(Ingredient.column_names, 'COUNT(*) recipe_count')
  .order('recipe_count DESC') # Or ASC