2

我有一个主题和一个项目模型。我在他们之间有一个多对多的屁股(HABTM 之一)。

在主题的索引页面中,我想显示每个主题拥有的项目数。所以我有

@topics = Topic.all(:include => [:projects])

在我的控制器中,到目前为止一切都很好。问题是项目模型太大了,查询还是很慢

Topic Load (1.5ms)   SELECT * FROM "topics" 

Project Load (109.2ms)   SELECT "projects".*, t0.topic_id as the_parent_record_id FROM "projects" INNER JOIN "projects_topics" t0 ON "projects".id = t0.project_id WHERE (t0.topic_id IN (1,2,3,4,5,6,7,8,9,10,11)) 

有没有办法让第二个查询不选择 * 而只是名称或 ID?因为 HABTM Ass 不支持 counter_cache,而且我真的不想自己实现它......所以有没有办法让第二个查询更快?

我只需要在不加载整个项目对象的情况下提取计数...

提前致谢,

尼古拉斯·霍克·伊萨萨

4

2 回答 2

4
  1. counter_cache is very easy to implement
  2. you can convert habtm to double has_many, i.e. has_many :projects_topics in both project and topic model (and belongs_to in projects_topics) and then use counter_cache or do eager loading only on projects_topics
  3. you can do :select => "count(projects_topics.id)", :group => "topics.id" but this won't work well with postgresql if you care about it...

The second option is the best IMO, I usually don't use habtm at all, only double has_many :)

于 2010-01-29T18:13:09.703 回答
0

要扩展 Devenv 的答案计数器缓存,您通常会在这种情况下使用。

来自 api 文档:

通过使用 increment_counter 和 decrement_counter 缓存关联类上的所属对象的数量。计数器缓存在创建此类对象时递增,在销毁时递减。这要求在关联类(例如 Post 类)上使用名为 #{table_name}_count 的列(例如属于 Comment 类的 comments_count)。您还可以通过为此选项提供列名而不是真/假值来指定自定义计数器缓存列(例如,:counter_cache => :my_custom_counter。)注意:指定计数器缓存会将其添加到该模型的只读列表中使用 attr_readonly 的属性。

是 ryan bates在 counter_cache 上的 railscast 的屏幕截图。

是我半年前提出的一个问题的答案,该问题的解决方案是一个易于实现的自制计数器缓存。

于 2010-01-30T18:15:39.840 回答