使用Active Record在同一查询中提供连接计数和总计数

时间:2012-11-06 10:01:02

标签: sql ruby-on-rails

一个风格有很多评论

让我说我在做:

Style.select('styles.id').
    joins(:reviews).
    select('reviews.style_id, count(reviews.id) AS review_count')

...但我也想知道评论的总数!是否也可以提取这些信息。我尝试将count(*)作为total_reviews,但这仍然会返回每个样式的审核计数。

1 个答案:

答案 0 :(得分:1)

如果你认为在SQL中,你正在构建很多行(好吧,那个批次的一个子集),并且在每行中你都要计算该行的数量。

另一方面,您需要总计数。哪个检索到的记录应该具有该总数以及哪个列/属性?

这不是你不能在rails中做到这一点,而是你不能在SQL本身那样做。 结果集完全不同,因此您需要两个查询,因此需要两个ActiveRecord调用。

另一种处理此问题的方法(同样需要两个单独的查询,但它们更简单)是对@style.reviews使用counter_cache:

# add a 'reviews_count' integer column to the 'styles' table and use it as 
# a counter cache as follows
class Review < AR::Base
  belongs_to :style, :counter_cache => true
end

现在您可以在不需要连接的情况下获得计数,并且可以通过简单的总和获得总计数。

附录:要使用ocounter缓存,请一如既往地查询styles表(不包含或加入),然后调用

@style.reviews.size

每当您想要获得评论的计数时。这不会进行另一个查询,而是使用@style实例本身的缓存计数器。