ログを見てるとDeviseのユーザーがログイン状態にあるかどうかのチェックで毎回SQLをはいているので、この部分をキャッシュできないかな?とDeviseとWardenのコードを追ってみました。
https://github.com/plataformatec/devise
https://github.com/hassox/warden
(ここではUserモデルがDeviseを使用してるとします。)
かなり省略しますが、最終的にはwarden_compat.rb内の deserializeが呼ばれ
klass = ActiveSupport::Inflector.constantize(klass_name)
if klass.respond_to? :serialize_from_session
klass.serialize_from_session(*args)
else
Rails.logger.warn "[Devise] Stored serialized class #{klass_name} seems not to be Devise enabled anymore. Did you do that on purpose?"
nil
end
そこでserialize_from_sessionを呼んでいます。
devise内のauthenticatable.rbを見ると
authenticatable.rb
def serialize_from_session(key, salt)
record = to_adapter.get(key)
record if record && record.authenticatable_salt == salt
end
どうやらここでUserデータを読み込んでいて、このモジュール自体はUserモデルでインクルードしているので、この部分をUserモデル上でオーバーライドすればできそうです。
def self.serialize_from_session(key, salt)
Rails.cache.fetch("#{User.name}_#{key[0]}") {
record = to_adapter.get(key)
record if record && record.authenticatable_salt == salt
}
end
もちろん適切なキャッシュのクリアは必要ですが、こんな感じでUserのデータをキャッシュできます。