いいねの件数をcounter_cacheを使ってキャッシュする方法

✏️️ 2019/08/30 👍️2019/08/30 🔗

記事(Post)がいいねされた件数をPosts テーブルに保存しておけば、いいね件数を取得するだけのために、Likes Tableを見に行く必要がなくなります。belongs_toメソッドのオプションであるcounter_cache を利用することでこのような仕組みを実現出来ます。

いいねの件数を保存するためのcolumnを作成

bin/rails generate migration AddLikesCountToPost likes_count:integer

マイグレーションファイル

class AddLikesCountToPost < ActiveRecord::Migration[6.0]
  def change
    add_column :posts, :likes_count, :integer, null: false, default: 0
  end
end

null: false, default: 0 にします。

マイグレーション

bin/rails db:migrate

Like モデルでcounter_chashを有効にする

# app/models/like.rb
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :post, counter_cache: true
end

like数を保存する先のカラム名が like_count(テーブル名_count)のようになってない場合は、counter_cache: like_num のようにします。

Viewで件数を表示する

<%= post.likes.size %>

※ lengthやcountだとcounter_cacheは機能しません。

確認

>  post.likes.size
Post Load (0.4ms)  SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT $1  [["LIMIT", 1]]
=> 0
>  post.likes.count
Post Load (0.6ms)  SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT $1  [["LIMIT", 1]]
   (1.3ms)  SELECT COUNT(*) FROM "likes" WHERE "likes"."post_id" = $1  [["post_id", 1]]
=> 0
> post.likes.length
  Post Load (0.4ms)  SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT $1  [["LIMIT", 1]]
  Like Load (0.4ms)  SELECT "likes".* FROM "likes" WHERE "likes"."post_id" = $1  [["post_id", 1]]
=> 0

以上で、いいねの件数をcounter_cacheを使ってキャッシュする方法は完了です。

Akito
日本のスタートアップで主にRuby on Railsを使ってプロダクト開発をしています。