コンピューター サイエンスの 2 つの難しい問題の 1 つ、キャッシュの無効化へようこそ :)
キャッシュされたオブジェクトが表示されるオブジェクトから単純に派生できるキャッシュされたビューとは異なり、キャッシュされたオブジェクトを無効にする必要がある場合のロジックは、アプリケーションと状況に依存するため、手動で処理する必要があります。
これがRails.cache.fetch
メソッドです。Rails.cache.fetch
3 つの引数を取ります。キャッシュ キー、オプション ハッシュ、およびブロック。まず、キーに基づいて有効なキャッシュ レコードを読み取ろうとします。そのキーが存在し、有効期限が切れていない場合は、キャッシュから値が返されます。有効なレコードが見つからない場合は、代わりにブロックから戻り値を取得し、指定したキーでキャッシュに保存します。
例えば:
@models = Rails.cache.fetch my_cache_key do
Model.where(condition: true).all
end
これにより、ブロックがキャッシュされ、何か (tm) がキーを無効にするまで結果が再利用され、ブロックの再評価が強制されます。.all
メソッドチェーンの最後にある にも注意してください。通常、Rails はキャッシュされる ActiveRecord リレーション オブジェクトを返します。これは、最初に使用しようとしたときに評価され、キャッシュを適切@models
に回避します。この.all
呼び出しにより、Rails は強制的にレコードを積極的にロードし、キャッシュするのは質問ではなく結果であることを確認します。
すべてのキャッシュをオンにして、二度とデータベースと通信しないようになったので、もう一方の端をカバーして、キャッシュを無効にする必要があります。これはRails.cache.delete
、単純にキャッシュ キーを取得して削除する方法で行われるため、次に取得しようとしたときにミスが発生します。force: true
fetch でオプションを使用して、ブロックの再評価を強制することもできます。どちらでも構いません。
すべての科学は を呼び出す場所です。Rails.cache.delete
単純なケースでは、これは単一のインスタンスの更新と削除、およびコレクションの任意のメンバーの更新、削除、作成になります。まれなケースが常にあり、それらは常にアプリケーション固有であるため、私はあなたを助けることはできません.
この回答では、memcached や Redis などの適切なキャッシュ ストアを設定することを前提としています。
また、これを忘れずに config/environments/development.rb に追加してください:
config.cache_store = :null_store
そうしないと、開発環境がキャッシュされ、フラストレーションから無毛になってしまいます。
詳細については、以下を参照してください: RailsおよびThe rails API docsでは、誰もが低レベルのキャッシュを使用する必要があります。
また、Rails 4 から機能が削除されたわけではなく、gem に抽出されただけであることも注目に値します。スイーパーの全機能が必要な場合、または使用したい場合はgem 'rails-observers'
、Gemfile に 1 行追加してアプリに戻すだけです。この gem には、Rails 4 コアから削除されたスイーパーとオブザーバーの両方が含まれています。
始めるのに役立つことを願っています。