LoginSignup
1
1

More than 5 years have passed since last update.

counter_cacheが便利だと思ったはなし

Last updated at Posted at 2019-02-07

はじめに

railsでcounter_cacheというものがあるのを知った。

今まで例えばいいね機能を付ける場合

rails g model user name:string 
rails g model star user:references

みたいにして

userのstarの数を知りたいときは

stars_count = Star.where(user_id: params[:id]).count

みたいにしていた

だがcounter_cacheを使うとstarが作成されたときに自動的にuserカラムのstars_countにstarの数を入れてくれる

使い方

models/user.rbに

user.rb
class User < ApplicationRecord
    has_many :stars
end

models/star.rbに

star.rb
class Star < ApplicationRecord
    belongs_to :user, :counter_cache => true
end

とする。

これで終わり。

ちなみにあらかじめuserにstars_countというカラムを作成しておく必要があります。

またstars_countではなくほかのカラム名にしたい場合は

:counter_cache => true

counter_cache: :sample_count

とすればOK

試しに使う

rails g model user name stars_count:integer
rails g model star 
rails db:migrate
rails c
user = User.create(name: "counter")
100.times {user.stars.create}

省略

"2019-02-07 12:03:41.796608"], ["updated_at", "2019-02-07 12:03:41.796608"], ["user_id", 2]]
  User Update All (0.2ms)  UPDATE "users" SET "stars_count" = COALESCE("stars_count", 0) + 1 WHERE "users"."id" = ?  [["id", 2]]
   (11.3ms)  commit transaction
   (0.1ms)  begin transaction
  Star Create (1.2ms)  INSERT INTO "stars" ("created_at", "updated_at", "user_id") VALUES (?, ?, ?)  [["created_at", "2019-02-07 12:03:41.812850"], ["updated_at", "2019-02-07 12:03:41.812850"], ["user_id", 2]]
  User Update All (0.1ms)  UPDATE "users" SET "stars_count" = COALESCE("stars_count", 0) + 1 WHERE "users"."id" = ?  [["id", 2]]
   (12.1ms)  commit transaction
   (0.1ms)  begin transaction
  Star Create (1.2ms)  INSERT INTO "stars" ("created_at", "updated_at", "user_id") VALUES (?, ?, ?)  [["created_at", "2019-02-07 12:03:41.831223"], ["updated_at", "2019-02-07 12:03:41.831223"], ["user_id", 2]]
  User Update All (0.1ms)  UPDATE "users" SET "stars_count" = COALESCE("stars_count", 0) + 1 WHERE "users"."id" = ?  [["id", 2]]
   (11.3ms)  commit transaction
   (0.1ms)  begin transaction
  Star Create (1.2ms)  INSERT INTO "stars" ("created_at", "updated_at", "user_id") VALUES (?, ?, ?)  [["created_at", "2019-02-07 12:03:41.847880"], ["updated_at", "2019-02-07 12:03:41.847880"], ["user_id", 2]]
  User Update All (0.1ms)  UPDATE "users" SET "stars_count" = COALESCE("stars_count", 0) + 1 WHERE "users"."id" = ?  [["id", 2]]
   (13.2ms)  commit transaction
=> 100

user.stars_count
=> 100

みたいにちゃんとできています:sunny:

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1