サーチ…


ロシアの人形のキャッシング

キャッシュされたフラグメントを他のキャッシュされたフラグメントにネストすることができます。これはRussian doll cachingと呼ばれています。

Russian doll cachingの利点は、単一の製品が更新された場合、外側のフラグメントを再生成するときに、他のすべての内部フラグメントを再利用できることです。

前のセクションで説明したように、キャッシュされたファイルが直接依存するレコードのupdated_atの値が変更された場合、キャッシュされたファイルは期限切れになります。ただし、これによりフラグメントがネストされたキャッシュは期限切れになりません。

たとえば、次のように表示します。

<% cache product do %>
  <%= render product.games %>
<% end %>

このビューをレンダリングします。

<% cache game do %>
  <%= render game %>
<% end %>

ゲームの属性が変更された場合、 updated_at値は現在の時刻に設定され、キャッシュが期限切れになります。

ただし、製品オブジェクトのupdated_atは変更されないため、キャッシュの有効期限は切れず、アプリは古いデータを処理します。これを修正するために、我々はモデルをタッチメソッドと結びつける:

class Product < ApplicationRecord
  has_many :games
end

class Game < ApplicationRecord
  belongs_to :product, touch: true
end

SQLキャッシュ

クエリキャッシュは、各クエリによって返された結果セットをキャッシュするRails機能です。 Railsがその要求に対して同じクエリを再度検出した場合、データベースに対してクエリを再度実行するのではなく、キャッシュされた結果セットを使用します。

例えば:

class ProductsController < ApplicationController

  def index
    # Run a find query
    @products = Product.all

    ...

    # Run the same query again
    @products = Product.all
  end

end

同じクエリがデータベースに対して2回目に実行されると、実際にはデータベースにヒットしません。結果がクエリから返された最初のときには、クエリキャッシュ(メモリ内)に格納され、2回目はメモリから取得されます。

ただし、クエリキャッシュはアクションの開始時に作成され、そのアクションの終わりに破棄されるため、アクションの持続時間中のみ持続することに注意することが重要です。より永続的な方法でクエリ結果を保存したい場合は、低レベルのキャッシュで行うことができます。

フラグメントキャッシング

Rails.cacheによって提供されているRails.cacheを使用して、リクエストにまたがってシリアライズ可能なRubyオブジェクトをキャッシュすることができます。

キャッシュから特定のキーの値をフェッチするには、 cache.read使用しcache.read

Rails.cache.read('city')
# => nil

cache.writeを使用して、キャッシュに値を書き込みます。

Rails.cache.write('city', 'Duckburgh')
Rails.cache.read('city')
# => 'Duckburgh'

代わりに、 cache.fetchを使用してキャッシュから値を読み込み、オプションで値がない場合はデフォルト値を書き込むこともできます。

Rails.cache.fetch('user') do
  User.where(:is_awesome => true)
end

渡されたブロックの戻り値は、指定されたキーのキャッシュに割り当てられてから返されます。

キャッシュの有効期限を指定することもできます。

Rails.cache.fetch('user', :expires_in => 30.minutes) do
  User.where(:is_awesome => true)
end

ページのキャッシュ

ActionPack page_caching gemを使用して個々のページをキャッシュすることができます。これにより、1つの動的要求の結果が静的HTMLファイルとして格納されます。このファイルは、後続の要求に対する動的要求の代わりに提供されます。 READMEには完全な設定手順が含まれています。設定したら、コントローラーのcaches_pageクラス・メソッドを使用して、アクションの結果をキャッシュします。

class UsersController < ActionController::Base
  caches_page :index
end

expire_pageを使用して、保存されたHTMLファイルを削除してキャッシュの有効期限を強制します。

class UsersController < ActionController::Base
  caches_page :index

  def index
    @users = User.all
  end

  def create
    expire_page :action => :index
  end
end

expire_pageの構文は、 url_forおよびfriendsの構文を模倣しています。

HTTPキャッシング

Rails> = 3には、HTTPキャッシュ機能が付属しています。これは、 Cache-ControlおよびETagヘッダーを使用して、クライアントまたは仲介者(CDNなど)がページをキャッシュできる期間を制御します。

コントローラーアクションでは、 expires_inを使用して、そのアクションのキャッシングの長さを設定します。

def show
  @user = User.find params[:id]
  expires_in 30.minutes, :public => true
end

expires_nowを使用して、訪問しているクライアントまたは仲介者にキャッシュされたリソースの即時有効期限を強制します。

def show
  @users = User.find params[:id]
  expires_now if params[:id] == 1
end

アクションキャッシング

ページキャッシュと同様に、アクションキャッシュはページ全体をキャッシュします。違いは、キャッシュが提供される前にフィルタが実行される前に、リクエストがRailsスタックにヒットすることです。それはRailsからactionpack-action_caching gemに抽出されました。

一般的な例は、認証が必要なアクションのキャッシュです。

class SecretIngredientsController < ApplicationController
  before_action :authenticate_user!, only: :index, :show
  caches_action :index
  
  def index
    @secret_ingredients = Recipe.find(params[:recipe_id]).secret_ingredients
  end
end

オプションには、 :expires_in 、custom :cache_path (複数の経路を別々にキャッシュする必要のあるアクション)、および/ :unlessアクションをキャッシュするタイミングを制御し:unless :if / :unless

class RecipesController < ApplicationController
  before_action :authenticate_user!, except: :show
  caches_page :show
  caches_action :archive, expires_in: 1.day
  caches_action :index, unless: { request.format.json? }
end

レイアウトに動的コンテンツがある場合は、 layout: falseを渡してアクションコンテンツのみをキャッシュしlayout: false



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow