短い答えをありがとう:キャッシュキーが無効の場合、キャッシュが更新されます。あなたのケースでは、特定の投稿のupdated_at
フィールドがキャッシュ内のものより遅い場合、キャッシュが更新されます。データベース内のデータが更新されたときではなく、ビューの新しいデータが最初にレンダリングされるときに、キャッシュの更新が行われることに注意することが重要です。
回答:基本的にはCaching with Railsとお読みください。
質問に投稿されたコードブロックは、Rails' Fragment Cachingを使用しています。 cache product
コールは、post.id
,post.updated_at
とビューテンプレートのMD5ハッシュの組み合わせであるキャッシュキーを生成します。 Railsはそのキーのキャッシュを検索し、見つかった場合は部分をレンダリングせずにキャッシュの値を返します。これはキャッシュヒットです。キャッシュキーが見つからない場合、Railsは部分をレンダリングし、将来の使用のためにキャッシュに結果を格納します。これはキャッシュミスです。
キャッシュスキームの難しい部分は、キャッシュの検証です。これは、キャッシュによって提供されるデータが有効で正確であることを保証するためです。たとえば、データベース内のデータが変更された場合、失効した(古い)キャッシュデータではなく、データベースデータを提供する必要があります。
Railsは、上記のキャッシュキーを構築することでこの問題を「自動的に」解決します。 post
レコードのデータが変更された場合は、post.updated_at
が更新され、新しいキャッシュキーが使用され、キャッシュミスが発生します。これは、キャッシュ内のデータが古い場合に起こりたいことです。同様に、ビューテンプレートが変更されると、ビューのMD5ハッシュが変更され、キャッシュキーも更新され、キャッシュミスが発生します。
shared/post_list
部分的に参照するデータまたは変数がpost
レコードに取り込まれていない場合、この問題が発生する可能性があります。たとえば、ユーザーが管理者であるかどうかによって部分的な変更が行われた場合、キャッシュキーにユーザーの管理者ステータスを取得する必要があります。
もう1つの共通の例は、ポストに関連する他のデータベースオブジェクトを参照する場合です。あなたの部分がpost.comments
のリストをレンダリングするという議論のために、コメントが変更されたが、その変更がpost
レコードのupdated_at
フィールドに接触しない場合、キャッシュによって提供されるデータは無効になります。
Class Comment < ActiveRecord:base
belongs_to :post, touch: true
...
end
上記のコードはpost
レコードのupdated_at
いつでもそのコメントの変更のいずれかを更新します。この問題はbelongs_to
協会にtouch: true
を追加することによって解決されます。
最後に、Railsはと呼ばれるものを提供します。これは、部分/テンプレートのコレクションをより効率的にレンダリングする方法です。あなたは、1行のコードで全体each
ループを置き換えることによって、あなたの例では、キャッシングのこのフォームを実現することができます。
<%= render partial: 'shared/post_list', collection: @posts, cached: true %>
ここで説明されるよりも、キャッシングの多くのがあります。この投稿にリンクされているガイドを読むことをお勧めします。そうすれば、キャッシュ検証を完全に理解することができます。キャッシングを使用すると、サーバーを大幅に高速化できます。場合によっては、サーバの応答時間が桁違いに低下することがあります。ただし、注意しない限り、キャッシュに古くなった日付が表示される可能性があります。
ありがとうございました!あなたの答えはとても役に立ちます! – rod