【问题标题】:Rails 4 ActiveRecord order by count of associationRails 4 ActiveRecord 按关联计数排序
【发布时间】:2015-11-27 22:10:38
【问题描述】:

有一个视图我要显示的内容

例如:

recipe.user.name 
recipe.name
recipe.picture
recipe.created_at

排序

recipe.likes.count

控制器:

@recipes_by_likes = Recipe.likes_count.paginate(page: params[:page])

型号:

Recipe has_many :likes

Like belongs_to :recipe

范围:

scope :likes_count, -> { 
  select('recipes.*, COUNT(likes.id) AS likes_count').
  joins(:likes).
  order('likes_count DESC')
}

但这给了我

SELECT  recipes.*, COUNT(likes.id) AS likes_count 
FROM "recipes" 
INNER JOIN "likes" ON "likes"."recipe_id" = "recipes"."id"  
ORDER BY "recipes"."created_at" DESC, likes_count DESC 
LIMIT 30 OFFSET 0

只返回 1 个(错误的)结果。

【问题讨论】:

标签: mysql ruby-on-rails activerecord named-scope


【解决方案1】:

1。查询

您不应该通过他们的id 来计算喜欢,因为它始终是唯一的并且总是返回 1,而是通过 recipe_id 这与某个食谱相关联的喜欢相同。

scope :likes_count, -> { 
  select('recipes.*, COUNT(likes.recipe_id) AS likes_count')
  .joins(:likes)
  .group('recipes.id')
  .order('likes_count DESC')
}

2。计数器缓存方法

您也可以使用counter_cache

class Like < ActiveRecord::Base
  belongs_to :recipe, counter_cache: true
end

并为Recipe模型添加一列

add_column :recipes, :likes_count, :integer, default: 0

【讨论】:

  • 得到:SELECT recipes.*, COUNT(likes.recipe_id) AS likes_count FROM "recipes" INNER JOIN "likes" ON "likes"."recipe_id" = "recipes"."id" ORDER BY "recipes"."created_at" DESC, likes_count DESC LIMIT 30 OFFSET 0 但只有 1 个结果
  • 为什么会有LIMITOFFSET?无论如何尝试将group("likes.recipe_id") 添加到您的上述查询中并告诉我您得到了什么。
  • SELECT recipes.*, COUNT(likes.recipe_id) AS likes_count FROM "recipes" INNER JOIN "likes" ON "likes"."recipe_id" = "recipes"."id" GROUP BY likes。 recipe_id ORDER BY "recipes"."created_at" DESC, likes_count DESC LIMIT 30 OFFSET 0 .. 7 个结果(没有喜欢的食谱除外)顺序错误
  • 更新了答案。还添加了counter_cache方法
  • 添加了你所描述的 counter_cache - 就像一个魅力!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多