Sök…


Russian Doll Caching

Du kanske vill häcka cachade fragment i andra cachade fragment. Detta kallas Russian doll caching .

Fördelen med Russian doll caching är att om en enda produkt uppdateras kan alla andra inre fragment återanvändas när det yttre fragmentet regenereras.

Som förklarats i föregående avsnitt kommer en cache-fil att löpa ut om värdet på updated_at ändras för en post som den cachade filen direkt beror på. Detta kommer dock inte att löpa ut någon cache som fragmentet kapslas in i.

Ta till exempel följande vy:

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

Som i sin tur ger denna åsikt:

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

Om något attribut för spelet ändras, kommer det updated_at värdet att ställas in på aktuell tid, varigenom cachen går ut.

Eftersom updated_at kommer att ändras för produktobjektet kommer den cachen inte att upphöra att gälla och din app kommer att visa inaktuella data. För att fixa detta binder vi modellerna med beröringsmetoden:

class Product < ApplicationRecord
  has_many :games
end

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

SQL-caching

Query-caching är en Rails funktion som cachar resultatuppsättningen som returneras av varje fråga. Om Rails möter samma fråga igen för den begäran, kommer den att använda det cachade resultatet som ställts i motsats till att köra frågan mot databasen igen.

Till exempel:

class ProductsController < ApplicationController

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

    ...

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

end

Andra gången samma fråga körs mot databasen kommer den inte att träffa databasen. Första gången resultatet returneras från frågan lagras det i frågecachen (i minnet) och andra gången det dras från minnet.

Det är emellertid viktigt att notera att fråga-cachemärken skapas i början av en åtgärd och förstöras i slutet av åtgärden och därmed endast kvarstår under hela åtgärden. Om du vill lagra frågeställningar på ett mer bestående sätt kan du göra det med cache-låga nivåer.

Fragment caching

Rails.cache , som tillhandahålls av ActiveSupport, kan användas för att cache-räkna alla seriellt Ruby-objekt över förfrågningar.

För att hämta ett värde från cachen för en given nyckel, använd cache.read :

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

Använd cache.write att skriva ett värde till cachen:

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

Alternativt kan du använda cache.fetch att läsa ett värde från cachen och skriva valfritt om det inte finns något värde:

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

Returvärdet för det passerade blocket tilldelas cachen under den angivna tangenten och returneras sedan.

Du kan också ange en cache-utgång:

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

Sidcache

Du kan använda ActionPack page_caching-pärla för att cachera enskilda sidor. Detta lagrar resultatet av en dynamisk begäran som en statisk HTML-fil, som serveras i stället för den dynamiska begäran på efterföljande förfrågningar. README innehåller fullständiga installationsinstruktioner. När du har caches_page använder caches_page metoden caches_page klass i en kontroller för att cache resultatet av en åtgärd:

class UsersController < ActionController::Base
  caches_page :index
end

Använd expire_page att tvinga cachens utgång genom att ta bort den lagrade HTML-filen:

class UsersController < ActionController::Base
  caches_page :index

  def index
    @users = User.all
  end

  def create
    expire_page :action => :index
  end
end

Syntaxen för expire_page efterliknar url_for och vänner.

HTTP-cache

Rails> = 3 kommer med HTTP-cachemöjligheter utanför rutan. Detta använder Cache-Control ETag och ETag rubrikerna för att kontrollera hur länge en klient eller mellanhand (t.ex. ett CDN) kan cache en sida.

I en kontrolleråtgärd använder du expires_in att ställa in cachelängden för den åtgärden:

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

Använd expires_now att tvinga omedelbar giltighetstid för en cache-resurs på alla besökande klienter eller mellanhand:

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

Åtgärd cache

Liksom cache-cache cache-caching cachar hela sidan. Skillnaden är att begäran träffar Rails-stacken så innan filter körs innan cachen serveras. Det är extraherat från Rails till actionpack-action_caching pärla .

Ett vanligt exempel är cachning av en åtgärd som kräver autentisering:

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

Alternativen inkluderar :expires_in , en anpassad :cache_path (för åtgärder med flera rutter som ska cachelagras annorlunda) och :if / :unless att kontrollera när åtgärden ska cache.

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

När layouten har dynamiskt innehåll cache- ras bara åtgärdsinnehållet genom att skicka layout: false .



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow