Rails渴望加载问题查找(:all,:include => [:model])

时间:2010-01-29 17:05:54

标签: ruby-on-rails activerecord eager-loading

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

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

@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,我真的不想自己实现它...所以有没有办法让第二个查询更快?

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

提前致谢,

NicolásHockIsaza

2 个答案:

答案 0 :(得分:4)

  1. counter_cache非常容易实现
  2. 您可以将habtm转换为double has_many,即项目和主题模型中的has_many:projects_topics(以及projects_topics中的belongs_to)然后使用counter_cache或仅在projects_topics上执行eager加载
  3. 你可以这样做:select => “count(projects_topics.id)”,:group => “topics.id”但如果您关心它,这将无法与postgresql一起使用......
  4. 第二个选项是最好的IMO,我通常根本不使用habtm,只有两个has_many:)

答案 1 :(得分:0)

扩展Devenv的答案counter cache是您通常用于此类场景的内容。

来自api docs:

  

缓存归属对象的数量   在关联类上通过使用   increment_counter和   decrement_counter。计数器缓存   当一个对象时,它会递增   class是在创建和递减时   它被摧毁了。这需要一个   名为#{table_name} _count的列(例如   作为所有物的comments_count   评论类)用于   关联类(如帖子   类)。您还可以指定自定义   通过提供一个计数器缓存列   列名而不是true / false   此选项的价值(例如,   :counter_cache => :my_custom_counter)。   注意:指定计数器缓存   将它添加到该模型的列表中   readonly属性使用   attr_readonly。

Here是ryan bates'railscasts在counter_cache上投放的屏幕。

Here是对我半年前提出的一个问题的回答,该问题解决方案是一个易于实现的家庭酿造柜台缓存。