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 .