Ruby on Rails
caching
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
.