rails: 计数器缓存(counter-cache)

在 Rails 中要实现 counter_cache: true,以便通过 authorbooks_count 来自动统计 Author 关联的 Book 数量,你需要执行以下步骤:

01 创建 Book 和 Author 模型

首先,生成 BookAuthor 模型。执行以下命令:

rails g model Author name:string
rails g model Book title:string author:references

02 添加 counter_cache 字段 ✅

为了支持 counter_cache: true,你需要在 authors 表中添加一个 books_count 列。生成一个新的迁移:

  • 一对多的Model中:  xx_count 加在 1 的 model 那一方
  • 一对多的Model中:  加在 belongs_to :author, counter_cache: true
# 重点是这个
rails g migration AddBooksCountToAuthors books_count:integer

03 确认迁移文件,添加 default: 0

修改生成的迁移文件,确保 books_count 默认值为 0,如下所示:

class AddBooksCountToAuthors < ActiveRecord::Migration[7.0]
  def change
    add_column :authors, :books_count, :integer, default: 0
  end
end

04 更新模型 counter_cache: true ✅

Book 模型中添加 counter_cache: true,如下所示:

class Book < ApplicationRecord
  belongs_to :author, counter_cache: true
end

Author 模型中保持 has_many :books

class Author < ApplicationRecord
  has_many :books
end

05 确保缓存计数更新

当你创建、更新或删除 Book 时,books_count 将自动更新,无需手动维护计数。如果你已经有现有的记录,你可能需要手动初始化计数:

Author.find_each { |author| Author.reset_counters(author.id, :books) }

这样,Rails 会根据现有的 Book 条目重置 Authorbooks_count

通过 counter_cache: true,你可以实现自动统计关联记录的数量,Rails 将在你创建或删除关联对象时,自动更新 Authorbooks_count

rubyonrails rails cache counter size count