如何在ActiveRecord查询中包含association.count,以便它不执行第二个查询?

时间:2011-09-03 16:06:10

标签: ruby-on-rails activerecord

在我的模特中,我经常有很多关联。我还经常需要显示有多少(即assoc.count)。这会强制执行另一个查询,如下所示:

ruby-1.8.7-p334 :020 > Instructor.first.instructors_lessons.count
  Instructor Load (0.5ms)  SELECT `users`.* FROM `users` INNER JOIN `instructor_profiles` ON `instructor_profiles`.`instructor_id` = `users`.`id` LIMIT 1
  SQL (1.2ms)  SELECT COUNT(*) FROM `instructors_lessons` WHERE (`instructors_lessons`.instructor_id = 2817)

当有一个或两个时,这很好,但是当有100个以上时,这个过程明显变慢。 请看这个极其缓慢的过程(http://pastebin.com/p4Sj7q7s)。我一直在使用缓存来处理一个非常慢的页面。

我可以把它放在这样的查询中:但这很乏味,有点挫败了ActiveRecord关联的目的:

 select("instructors.*, count('instructors_lessons.instructor_id') as num_lessons").

但是我不能简单地说一下instructor.lessons.count ......

有没有办法使用join()或includes(),以便不需要执行这个额外的COUNT()查询?

1 个答案:

答案 0 :(得分:7)

听起来你正在寻找counter cache

您只需使用_count创建一个列,然后在您所属的关联中指定counter_cache。

在您的情况下,您将向教师列添加一个名为“lessons_count”的字段。然后执行以下操作:

belongs_to :instructor, :counter_cache => true

当相关记录总数发生变化时,此值将自动更新总计。