Counter Cache Column

If you need to display the record count for a has_many association, you can improve performance by caching that number in a column.
 
如果你需要显示某个对象所关联对象的个数,你可以在一个字段中缓存这个数字。
 
例:
List Projects
 
project1(10tasks)
project2(15tasks)
project3(20tasks)
 
看一下代码:
# projects_controller.rb
def index
    @projects=Project.find(:all)
end
 
#index.rhtml
 
<% @projects.each do |project|%>
     <%= project.name%><small>(<%= pluralize project.tasks.size , 'task'%>)</small>
<%end%>
 
 
但是在日志中,我们看到,对project的每一个对象,都要进行一次SQL查询得到task的个数。
利用上节提到过的贪婪加载,可以在index这个action里
def index
     @projects=Project.find(:all, :include=>:tasks)
end
 
这样就可以通过一条SQL查询语句得到想要显示的结果了。但是这样的查询语句会将很多不需要的信息也进行查询。
现在我们只需要关联的tasks的数量
 
所以我们想到在project表中加入一个统计每一个对象拥有的tasks数量的这样一个字段。方法:
script/generate migration add_tasks_count
def self.up
add_column :projects, :tasks_count, :integer,:default=>0
Project.reset_column_information
Project.find(:all).each do |p|
    p.update_attribute :tasks_count, p.tasks.length
end
end
def self.down
remove_column :projects, :tasks_count
end
 
>rake db:migrate
 
这样就加载上缓存字段了。
还有重要的一步,要在task.rb中加上
class Task <ActiveRecord::Base
   belongs_to :project, :counter_cache=>true
 end
 
 
---------
reset_column_information()
Resets all the cached information about columns, which will cause them to be reloaded on the next request.