Ruby on Rails
caching
Zoeken…
Russische Doll Caching
Misschien wilt u gecachte fragmenten nesten in andere gecachte fragmenten. Dit wordt Russian doll caching
.
Het voordeel van Russian doll caching
is dat als een enkel product wordt bijgewerkt, alle andere binnenste fragmenten kunnen worden hergebruikt bij het regenereren van het buitenste fragment.
Zoals in de vorige sectie is uitgelegd, verloopt een in de cache opgeslagen bestand als de waarde van updated_at
verandert voor een record waarvan het in de cache opgeslagen bestand direct afhangt. Hierdoor vervalt echter geen cache waarin het fragment is genest.
Neem bijvoorbeeld de volgende weergave:
<% cache product do %>
<%= render product.games %>
<% end %>
Wat op zijn beurt deze opvatting weergeeft:
<% cache game do %>
<%= render game %>
<% end %>
Als een kenmerk van het spel wordt gewijzigd, wordt de waarde updated_at
ingesteld op de huidige tijd, waardoor de cache verloopt.
Omdat updated_at
echter niet wordt gewijzigd voor het productobject, zal die cache niet verlopen en zal uw app oude gegevens weergeven. Om dit op te lossen, koppelen we de modellen aan elkaar met de aanraakmethode:
class Product < ApplicationRecord
has_many :games
end
class Game < ApplicationRecord
belongs_to :product, touch: true
end
SQL Caching
Query-caching is een functie Rails
die de resultatenset cachet die wordt geretourneerd door elke query. Als Rails
dezelfde query opnieuw tegenkomt voor die aanvraag, gebruikt deze de in de cache opgeslagen resultaatset in plaats van de query opnieuw uit te voeren in de database.
Bijvoorbeeld:
class ProductsController < ApplicationController
def index
# Run a find query
@products = Product.all
...
# Run the same query again
@products = Product.all
end
end
De tweede keer dat dezelfde query op de database wordt uitgevoerd, zal deze de database niet bereiken. De eerste keer dat het resultaat van de query wordt geretourneerd, wordt het opgeslagen in de querycache (in het geheugen) en de tweede keer wordt het uit het geheugen gehaald.
Het is echter belangrijk op te merken dat query-caches worden gemaakt aan het begin van een actie en worden vernietigd aan het einde van die actie en dus alleen blijven bestaan voor de duur van de actie. Als u queryresultaten op een meer persistente manier wilt opslaan, kunt u met caching op laag niveau.
Fragment caching
Rails.cache
, aangeboden door ActiveSupport, kan worden gebruikt om elk serialiseerbaar Ruby-object in verschillende cache op te slaan.
Gebruik cache.read
om een waarde op te halen uit de cache voor een bepaalde sleutel.
Rails.cache.read('city')
# => nil
Gebruik cache.write
om een waarde naar de cache te schrijven:
Rails.cache.write('city', 'Duckburgh')
Rails.cache.read('city')
# => 'Duckburgh'
U kunt ook cache.fetch
gebruiken om een waarde uit de cache te lezen en optioneel een standaard te schrijven als er geen waarde is:
Rails.cache.fetch('user') do
User.where(:is_awesome => true)
end
De retourwaarde van het doorgegeven blok wordt toegewezen aan de cache onder de gegeven sleutel en vervolgens geretourneerd.
U kunt ook een cache-vervaldatum opgeven:
Rails.cache.fetch('user', :expires_in => 30.minutes) do
User.where(:is_awesome => true)
end
Paginacaching
U kunt de ActionPack page_caching gem gebruiken om afzonderlijke pagina's in het cachegeheugen op te slaan . Dit slaat het resultaat van een dynamisch verzoek op als een statisch HTML-bestand, dat in plaats van het dynamische verzoek bij volgende verzoeken wordt geserveerd. De README bevat volledige installatie-instructies. Gebruik na het caches_page
de caches_page
class-methode in een controller om het resultaat van een actie in de cache te plaatsen:
class UsersController < ActionController::Base
caches_page :index
end
Gebruik expire_page
om het verlopen van de cache te forceren door het opgeslagen HTML-bestand te verwijderen:
class UsersController < ActionController::Base
caches_page :index
def index
@users = User.all
end
def create
expire_page :action => :index
end
end
De syntaxis van expire_page
bootst die van url_for
en vrienden na.
HTTP-caching
Rails> = 3 wordt standaard geleverd met HTTP-cachemogelijkheden. Dit maakt gebruik van de Cache-Control
en ETag
headers om te bepalen hoe lang een client of intermediair (zoals een CDN) een pagina kan cachen.
Gebruik in een controlleractie expires_in
om de lengte van de cache voor die actie in te stellen:
def show
@user = User.find params[:id]
expires_in 30.minutes, :public => true
end
Gebruik expires_now
om de vervaldatum van een bron in het cachegeheugen op elke bezoekende client of tussenpersoon te forceren:
def show
@users = User.find params[:id]
expires_now if params[:id] == 1
end
Actie caching
Net als paginacaching, slaat actiecaching de hele pagina op in het cachegeheugen. Het verschil is dat het verzoek de stapel Rails raakt, dus voordat filters worden uitgevoerd voordat de cache wordt bediend. Het is geëxtraheerd uit Rails naar actionpack-action_caching gem .
Een veelvoorkomend voorbeeld is het cachen van een actie die authenticatie vereist:
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
Opties omvatten :expires_in
, een aangepast :cache_path
(voor acties met meerdere routes die anders in de cache moeten worden opgeslagen) en :if
/ :unless
om te bepalen wanneer de actie in de cache moet worden geplaatst.
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
Wanneer de lay-out dynamische inhoud heeft, cache dan alleen de actie-inhoud door de layout: false
door te geven layout: false
.