我有一个带有“食谱”模型的Rails应用程序。食谱可以被用户喜欢(“喜欢”模型)。我最终想要实现的是按喜欢的次数对食谱索引页面上的食谱列表进行排序。
我看过很多线程,但最能指导我的两个线程是:
Rails 3 ActiveRecord: order and group by association count
Rails order by results count of has_many association
到目前为止,我有一个SQL查询,该查询可生成配方列表以及其喜欢的次数:
SELECT recipes.name, COUNT(likes.id)
FROM recipes
LEFT JOIN likes on recipes.id = likes.recipe_id
GROUP BY recipes.name
ORDER BY COUNT(likes.id) DESC;
但是,当将其“翻译”为ActiveRecord可以理解的内容时,我遇到了麻烦。
我得出的结论是,使用Recipe.joins(:likes)或Recipe.left_joins(:likes)会传递“食谱”中指定的所有列,这会导致以下错误:
“列“ recipes.id”必须出现在GROUP BY子句中或在聚合函数中使用...“。
现在,由于我只需要传递配方名称和COUNT(likes.id),因此我使用了select:
Recipe.select("recipes.name, COUNT(likes.id)").joins(:likes).group("recipes.name").order("COUNT(likes.id) DESC")
这就是我受困的地方:
ActiveRecord :: Relation [配方ID:无,名称:“ Scrambled eggz”,配方ID:无,名称:“ Soup”,配方ID:无,名称:“ Nutella pancakes”]
答案 0 :(得分:1)
Recipe.joins("LEFT JOIN likes ON recipes.id = likes. recipe_id").group("recipes.id").order("COUNT(likes.id) ASC")
ActiveRecord解析期望返回的结果集具有原始模型具有的列(或列的子集)。
在选择原始列的子集时,ActiveRecord会在解析ActiveRecord对象/关系中的所有其他列时使其无效
答案 1 :(得分:1)
如果您想在活动记录查询中使用它,这可能对您有所帮助:
Recipe.left_joins(:likes).group(:id).order("COUNT(likes.id) DESC")
JOIN 警告:
Recipe.joins(:likes).group(:id).order("COUNT(likes.id) DESC")
这个查询只会返回有喜欢的菜谱。如果有没有任何喜欢的食谱,执行 JOINS 不会让你得到那些。
答案 2 :(得分:0)
您的查询是正确的。请注意,它使用Recipe
模型类,该模型类中没有包含您的自定义字段。如果您的查询是
Recipe.select("COUNT(likes.id)").joins(:likes).group("recipes.name").order("COUNT(likes.id) DESC")
它将向您显示
ActiveRecord::Relation [Recipe id: nil, Recipe id: nil, Recipe id: nil]
但是,您仍然可以访问自定义字段,返回的数据将保留它供您使用。您只需要给它起一个名字即可。另外,您可以使用该自定义字段进行订购,请不要直接订购COUNT
recipes = Recipe.select("COUNT(likes.id) as total_likes").joins(:likes).group("recipes.name").order("total_likes DESC")
recipe.first.total_likes # TOTAL LIKE of first recipe