Ruby on rails Rails—通过关联模型的计数将特定列传递给查询

Ruby on rails Rails—通过关联模型的计数将特定列传递给查询,ruby-on-rails,ruby,postgresql,rails-activerecord,Ruby On Rails,Ruby,Postgresql,Rails Activerecord,我有一个rails应用程序的“食谱”模型。配方可以被用户喜欢(“喜欢”模型)。我希望(最终)实现的是按照喜欢的数量对recipes index页面上的食谱列表进行排序 我见过很多线索,但其中最能引导我的是: 到目前为止,我已经有了一个SQL查询,它生成了一个食谱列表,其中包含了他们喜欢的食谱的数量: SELECT recipes.name, COUNT(likes.id) FROM recipes LEFT JOIN likes on recipes.id = likes.recipe_id

我有一个rails应用程序的“食谱”模型。配方可以被用户喜欢(“喜欢”模型)。我希望(最终)实现的是按照喜欢的数量对recipes index页面上的食谱列表进行排序

我见过很多线索,但其中最能引导我的是:

到目前为止,我已经有了一个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”中指定的所有列,这会导致以下错误:

“列”recipes.id“必须出现在GROUP BY子句中,或用于聚合函数…”

现在,由于我只需要传递recipes.name和COUNT(likes.id),我使用了select:

Recipe.select("recipes.name, COUNT(likes.id)").joins(:likes).group("recipes.name").order("COUNT(likes.id) DESC")
这就是我被困的地方,因为它产生了这个:

ActiveRecord::Relation[配方id:nil,名称:“炒鸡蛋”,配方id:nil,名称:“汤”,配方id:nil,名称:“坚果煎饼”]

ActiveRecord解析期望返回的结果集具有原始模型具有的列(或列的子集)

当选择原始列的子集时,ActiveRecord会在ActiveRecord对象/关系中解析其他所有列,并使其为空

ActiveRecord解析期望返回的结果集具有原始模型具有的列(或列的子集)


当选择原始列的子集时,ActiveRecord会在ActiveRecord对象/关系中解析所有其他列时使其为空。请注意,它使用
Recipe
model类,该类中不包含自定义字段。如果你的问题是

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

你的问题是正确的。请注意,它使用
Recipe
model类,该类中不包含自定义字段。如果你的问题是

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

如果您想在活动记录查询中使用它,这可能会对您有所帮助:

Recipe.left_joins(:likes).group(:id).order("COUNT(likes.id) DESC")
加入警告:

Recipe.joins(:likes).group(:id).order("COUNT(likes.id) DESC")

此查询将只返回有喜好的菜谱。如果有任何菜谱没有任何喜好,那么执行加入操作将无法获得这些喜好。

如果您想在活动记录查询中使用它,这可能会对您有所帮助:

Recipe.left_joins(:likes).group(:id).order("COUNT(likes.id) DESC")
加入警告:

Recipe.joins(:likes).group(:id).order("COUNT(likes.id) DESC")

此查询将只返回有喜好的菜谱。如果有任何食谱没有任何喜好,那么做加入不会让你得到这些。

请详细说明一下。所有这些函数都是做什么的?为什么这样做。仅仅删除一行代码并不是一个令人敬畏的答案。请教育未来的访客。请详细说明一下。所有这些函数都是做什么的?为什么这样做。仅仅删除一行代码并不是一个令人敬畏的答案。请教育未来的访客。为什么要避免直接按计数订购?为什么要避免直接按计数订购?