はじめに
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
みたいにちゃんとできています