我有两个型号
class User
has_many :subscriptions
end
和
class Subscription
belongs_to :user
end
我的一个页面我想显示按每个用户订阅数量排序的所有用户的列表。我不喜欢sql查询,但我认为
list = Users.all.joins(:subscriptions).group("user.id").order("count(subscriptions.id) DESC")
这份工作很重要。现在我的问题是,当我尝试使用list
计算list.count
中的对象总数时,我得到一个带user.id
的哈希和订阅计数,就像这样
{11 => 5,
8 => 7,
1 => 11,
...}
如果我的列表按用户名(在用户表中)排序,则list
.. .count
中的用户总数不会正常工作。我真的想使用.count
,因为它在一个宝石中的分页模块中,但任何想法都很棒!
谢谢!
答案 0 :(得分:0)
我们可以使用单个查询来完成此操作:
User.joins("LEFT OUTER JOIN ( SELECT user_id, COUNT(*) as num_subscriptions
FROM subscriptions
GROUP BY user_id
) AS temp
ON temp.user_id = users.id")
.order("temp.num_subscriptions DESC")
基本上,我的想法是尝试查询子查询中每个user_id
的订阅数,然后加入User
。我使用了LEFT OUTER JOIN
,因为会有几个users
没有任何subscriptions
改进选项:您可以在User
内定义范围,以后的使用会更美观:
<强> user.rb 强>
class User < ActiveRecord::Base
has_many :subscriptions
scope :sorted_by_num_subscriptions, -> {
joins("LEFT OUTER JOIN ( SELECT user_id, COUNT(*) as num_subscriptions
FROM subscriptions
GROUP BY user_id
) AS temp
ON temp.user_id = users.id")
.order("temp.num_subscriptions DESC")
}
end
然后使用它:
User.sorted_by_num_subscriptions
答案 1 :(得分:0)
当group
时,count
方法改变了它的行为,实际上,它返回每个组的计数哈希值,而不是返回记录的总数。 (有关详细信息,请参阅docs)。因此,您使用list.count
获得的只是每个用户的订阅计数的哈希值。
因此,您的查询是正确的,您只需要总结各组中的个别计数。这可以通过以下方式完成:
total_count = list.count.values.sum
如果分页调用仅仅调用问题的count
,则分页代码通常能够接受具有总计数的参数。例如,will_paginate接受total_entries
参数,因此您应该能够将总计数传递给它:
list.paginate(page: 2, total_entries: list.count.values.sum)