概要
前回 Postgres を使って Rails6 に入門しました
今回はそのアプリを使って Rails のクエリキャッシュ機能を使ってみたいと思います
簡単に言えば同じクエリは毎回データベースに問い合わせせずにメモリや Redis にキャッシュするという機能です
Rails のバージョンによって構文や使い方が異なるので注意してください
環境
- macOS 10.15.4
- Rails 6.0.2.2
- Redis 5.0.5
キャッシュの有効化
rails dev:cache
キャッシュするクエリをモデルで定義する
vim app/models/my_task.rb
class MyTask < ApplicationRecord
def self.cache_all
Rails.cache.fetch("#{cache_versioning}/list", expires_in: 30.seconds) do
MyTask.order(posted_date: "DESC").all.to_a
end
end
end
ポイントは最後に to_a
を付けて配列として返している点です
コントローラでキャッシュを参照するメソッドを使う
vim app/controllers/my_tasks_controller.rb
class MyTasksController < ApplicationController
protect_from_forgery
def list
@my_tasks = MyTask.cache_all
end
# 一部省略・・・
end
動作確認
rails s
で起動して localhost:3000/my_tasks
にアクセスしてみましょう
c=0 && while :;do ((c ++)); echo $c; curl localhost:3000/my_tasks > /dev/null 2>&1; sleep 1; done
紹介のアクセスは SQL が発行されていますが 2 回目以降は 30 秒経過するまでは SQL が発行されていないのがログから確認できると思います
おまけ: redis をキャッシュにする方法
上記はメモリ上にキャッシュを持っており参照するのが大変です
そんな場合は redis を使いましょう
redis のインストール
vim Gemfile
gem "redis_rails"
bundle install
config.cache_store の変更
設定ファイルを変更してオンメモリだったキャッシュ先を redis に変更します
Rails6 では :redis_cache_store, { url: ENV['REDIS_URL'] }
vim config/environments/development.rb
(一部省略)
if Rails.root.join('tmp', 'caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true
# config.cache_store = :memory_store
config.cache_store = :redis_cache_store, { url: "redis://192.168.100.1/0" }
config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
あとは redis を起動してアプリで確認すればキャッシュが redis に作成されていることが確認できると思います
192.168.100.1:6379> keys *
1) "true/list"
192.168.100.1:6379> TTL true/list
(integer) 19
データ自体は圧縮されていて平文では確認が難しい状態になっています
redis のエンドポイントに関する細かい設定は参考サイトにあるドキュメントを確認してください
最後に
Rails6 で Rails.cache を使ってみました
かなり簡単に使えました
リアルタイムでの表示が不要であったりデータがすぐに反映されなくても良いようなビューを扱う場合はかなり使える技だと思います
今回は SQL 文の発行をキャッシュしましたがビューの情報やネスト構造の一部だけをキャッシュするロシアンドールキャッシングなどもありいろいろな情報をキャッシュすることができます