5
4

More than 5 years have passed since last update.

Deviseで使用するmodelのインスタンスをキャッシュする

Posted at

ログを見てると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のデータをキャッシュできます。

5
4
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
5
4