保华的Rails学习笔记

counter cache的配置步骤

counter cache主要是用来优化数据库存查询的,例如在下边的应用场景下:

class Group < ApplicationRecord
  has_many :posts
end
class Post < ApplicationRecord
  belongs_to :group
end

在执行语句group.posts.count时,服务器log信息如下:


出现了很多个count(*),可是count(*)是很费服务器的效能的,如果数据量足够的时候,影响是非常大的

这正是counter cache要做的事情
它配置的步骤如下:

1、在post.rb中(belongs_to的一方),添加counter_cache: true

即把之前的belongs_to :group这一行修改为:
belongs_to :group, counter_cache: true

2、在groups表(即has_many的一方)中增加一个posts_count栏位

1)执行 rails g migration add_posts_count_to_group

2)在新产生的db/migrate/xxx_posts_count_to_group.rb文件中,添加

   add_column :groups, :posts_count, :integer, default: 0

    Group.pluck(:id).each do |i|
      Group.reset_counters(i, :posts) # 全部重算一次
    end

其中,后三行代码如果不加,那么counter cache对于之前的数据就没优化成功,所以需要添加上,重新计算,这样对于之前的历史数据,counter cache也可以起作用了

3)执行 rake db:migrate

注意:第1步与第2步,不能颠倒,如果先增加栏位,在rake db:migrate的时候,就会报错如下:


需要先修改post.rb,才能增加栏位posts_count

3、修改app/views/account/groups/index.html.erb页面中

把<%= group.posts.count %>修改为
<%= group.posts_count %>或者<%= group.posts.size %>
这样就配置完成了,现在log信息显示如下:

如果要查询posts_count这个栏位是否生效,可以去rails console中,用Group.all查询这个栏位的值