Rails

ActiveRecordのcounter_cacheでDBではなくcache_storeを使う

More than 1 year has passed since last update.


ActiveRecord counter_cache とは

ActiveRecord counter_cacheは子要素の要素数をキャッシュする機能です。


post.rb

class Post < ActiveRecord::Base

has_many :comments
end


comment.rb

class Comment < ActiveRecord::Base

belongs_to :post, counter_cache: true
end

post = Post.create(title: 'post title')

post.comments.create(body: 'comment')

post.comments_count # => 1

post.comments.last.destroy

post.comments_count # => 0

このように、子要素のモデル数を親モデルのあるfieldにcacheすることができる機能です。

FYI: http://qiita.com/tachiba/items/797ea74e7eeb7f32f886


やりたい



  • belongs_to :parent, counter_cache: true は分かりづらい


    • counter_cacheによりincr/decrするfieldを持つ親要素に子要素をキャッシュさせることを表記したほうが良いのでは?



  • それぞれのアプリケーションのcache_storeを使って高速にカウンタを読み込めるようにしたい


作った

https://github.com/iguchi1124/counter_cache-rails


使い方

Gemfileに追記


Gemfile

gem 'counter_cache-rails'


親要素のモデルに counter_cache ":#{modelの複数形}" で子要素のモデル名を複数形で指定する。


post.rb

class Post < ActiveRecord::Base

has_many :comments
counter_cache :comments
end


comment.rb

class Comment < ActiveRecord::Base

belongs_to :post
end

最後にRails.cache_storeを設定する。


config/application.rb

class Application < Rails::Application

# redis-rails
# config.cache_store = :redis_store, 'redis://localhost:6379/0/cache', { expires_in: 90.minutes }

# dalli
# config.cache_store = :mem_cache_store, 'localhost:11211'

config.cache_store = :memory_store
end



確認

post = Post.create(title: 'post title')

post.comments.create(body: 'comment')

post.comments_count # => 1

post.comments.last.destroy

post.comments_count # => 0