Ruby on Rails
Caching
Suche…
Russisches Puppen-Caching
Sie können zwischengespeicherte Fragmente in anderen zwischengespeicherten Fragmenten verschachteln. Dies wird als Russian doll caching
.
Das Russian doll caching
bietet den Vorteil, dass bei der Aktualisierung eines einzelnen Produkts alle anderen inneren Fragmente beim Regenerieren des äußeren Fragments wiederverwendet werden können.
Wie im vorherigen Abschnitt erläutert, updated_at
eine zwischengespeicherte Datei, wenn sich der Wert von updated_at
für einen Datensatz ändert, von dem die zwischengespeicherte Datei direkt abhängt. Dadurch verfällt jedoch kein Cache, in dem das Fragment verschachtelt ist.
Nehmen Sie zum Beispiel die folgende Ansicht:
<% cache product do %>
<%= render product.games %>
<% end %>
Was wiederum diese Ansicht wiedergibt:
<% cache game do %>
<%= render game %>
<% end %>
Wenn ein Attribut des Spiels geändert wird, wird der updated_at
Wert auf die aktuelle Uhrzeit gesetzt, wodurch der Cache abläuft.
Da jedoch updated_at
für das Produktobjekt nicht geändert wird, ist der Cache nicht abgelaufen, und Ihre App updated_at
veraltete Daten. Um dies zu beheben, binden wir die Modelle mit der Touch-Methode zusammen:
class Product < ApplicationRecord
has_many :games
end
class Game < ApplicationRecord
belongs_to :product, touch: true
end
SQL-Caching
Abfrage-Caching ist eine Rails
Funktion, die die von jeder Abfrage zurückgegebene Ergebnismenge zwischenspeichert. Wenn Rails
dieselbe Abfrage erneut für diese Anforderung findet, verwendet es die zwischengespeicherte Ergebnismenge, Rails
die Abfrage erneut für die Datenbank auszuführen.
Zum Beispiel:
class ProductsController < ApplicationController
def index
# Run a find query
@products = Product.all
...
# Run the same query again
@products = Product.all
end
end
Wenn die gleiche Abfrage zum zweiten Mal für die Datenbank ausgeführt wird, wird sie nicht wirklich die Datenbank treffen. Wenn das Ergebnis zum ersten Mal von der Abfrage zurückgegeben wird, wird es im Abfrage-Cache (im Speicher) gespeichert, und das zweite Mal wird es aus dem Speicher abgerufen.
Beachten Sie jedoch, dass Abfrage-Caches zu Beginn einer Aktion erstellt und am Ende dieser Aktion gelöscht werden und daher nur für die Dauer der Aktion bestehen bleiben. Wenn Sie die Abfrageergebnisse dauerhaft speichern möchten, können Sie die Zwischenspeicherung auf niedriger Ebene verwenden.
Fragment-Caching
Rails.cache
, bereitgestellt von ActiveSupport, kann verwendet werden, um jedes serialisierbare Ruby-Objekt zwischen Anforderungen zwischenzuspeichern.
Verwenden Sie cache.read
um einen Wert für einen bestimmten Schlüssel aus dem Cache cache.read
.
Rails.cache.read('city')
# => nil
Verwenden Sie cache.write
, um einen Wert in den Cache zu schreiben:
Rails.cache.write('city', 'Duckburgh')
Rails.cache.read('city')
# => 'Duckburgh'
Alternativ können Sie cache.fetch
, um einen Wert aus dem Cache zu lesen und optional einen Standardwert zu schreiben, wenn kein Wert vorhanden ist:
Rails.cache.fetch('user') do
User.where(:is_awesome => true)
end
Der Rückgabewert des übergebenen Blocks wird dem Cache unter dem angegebenen Schlüssel zugewiesen und anschließend zurückgegeben.
Sie können auch einen Cache-Ablauf angeben:
Rails.cache.fetch('user', :expires_in => 30.minutes) do
User.where(:is_awesome => true)
end
Zwischenspeicherung der Seite
Mit dem ActionPack page_caching können Sie einzelne Seiten zwischenspeichern. Dadurch wird das Ergebnis einer dynamischen Anforderung als statische HTML-Datei gespeichert, die bei nachfolgenden Anforderungen anstelle der dynamischen Anforderung bereitgestellt wird. Die Readme-Datei enthält vollständige Anweisungen zur Installation. Verwenden Sie nach dem caches_page
Klassenmethode caches_page
in einem Controller, um das Ergebnis einer Aktion zwischenzuspeichern:
class UsersController < ActionController::Base
caches_page :index
end
Verwenden Sie expire_page
, um den Ablauf des Caches durch Löschen der gespeicherten HTML-Datei zu erzwingen:
class UsersController < ActionController::Base
caches_page :index
def index
@users = User.all
end
def create
expire_page :action => :index
end
end
Die Syntax von expire_page
ahmt die von url_for
und friends nach.
HTTP-Caching
Rails> = 3 verfügt über HTTP-Caching-Funktionen. Dies verwendet die Header Cache-Control
und ETag
zu steuern, wie lange ein Client oder ein Vermittler (z. B. ein CDN) eine Seite zwischenspeichern kann.
Verwenden expires_in
in einer Controller-Aktion expires_in
, um die Länge der Zwischenspeicherung für diese Aktion expires_in
:
def show
@user = User.find params[:id]
expires_in 30.minutes, :public => true
end
Verwenden Sie expires_now
, um den sofortigen Ablauf einer zwischengespeicherten Ressource für jeden Besucherkunden oder expires_now
zu erzwingen:
def show
@users = User.find params[:id]
expires_now if params[:id] == 1
end
Action-Caching
Wie beim Seiten-Caching wird beim Action-Caching die gesamte Seite zwischengespeichert. Der Unterschied besteht darin, dass die Anforderung den Rails-Stack trifft, bevor Filter ausgeführt werden, bevor der Cache bereitgestellt wird. Es wird aus Rails zu actionpack-action_caching gem extrahiert.
Ein häufiges Beispiel ist das Zwischenspeichern einer Aktion, für die eine Authentifizierung erforderlich ist:
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
Zu den Optionen gehören :expires_in
, ein custom :cache_path
(für Aktionen mit mehreren Routen, die unterschiedlich zwischengespeichert werden sollten) und :if
/ :unless
gesteuert, wann die Aktion zwischengespeichert werden soll.
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
Wenn das Layout über dynamischen Inhalt verfügt, zwischenspeichern Sie nur den Aktionsinhalt, indem Sie das layout: false
.