Recherche…


Poupée Russe Caching

Vous souhaiterez peut-être imbriquer des fragments en cache dans d'autres fragments mis en cache. Cela s'appelle Russian doll caching .

L'avantage de Russian doll caching est que si un seul produit est mis à jour, tous les autres fragments internes peuvent être réutilisés lors de la régénération du fragment externe.

Comme expliqué dans la section précédente, un fichier mis en cache expirera si la valeur de updated_at change pour un enregistrement dont dépend directement le fichier en cache. Cependant, cela n'expire aucun cache dans lequel le fragment est imbriqué.

Par exemple, prenez la vue suivante:

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

Qui à son tour rend cette vue:

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

Si un attribut de jeu est modifié, la valeur updated_at sera définie sur l'heure actuelle, expirant ainsi le cache.

Cependant, parce que updated_at ne sera pas modifié pour l'objet produit, ce cache ne sera pas expiré et votre application servira les données obsolètes. Pour résoudre ce problème, nous lions les modèles avec la méthode tactile:

class Product < ApplicationRecord
  has_many :games
end

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

Mise en cache SQL

La mise en cache des requêtes est une fonctionnalité Rails qui met en cache l'ensemble de résultats renvoyé par chaque requête. Si Rails rencontre à nouveau la même requête pour cette requête, il utilisera le jeu de résultats mis en cache au lieu d'exécuter à nouveau la requête sur la base de données.

Par exemple:

class ProductsController < ApplicationController

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

    ...

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

end

La deuxième fois que la même requête est exécutée sur la base de données, elle ne touchera pas réellement la base de données. La première fois que le résultat est renvoyé par la requête, il est stocké dans le cache de la requête (en mémoire) et la deuxième fois dans la mémoire.

Cependant, il est important de noter que les caches de requêtes sont créés au début d'une action et détruits à la fin de cette action et ne persistent donc que pendant la durée de l'action. Si vous souhaitez stocker les résultats de la requête de manière plus persistante, vous pouvez utiliser la mise en cache de bas niveau.

Mise en cache des fragments

Rails.cache , fourni par ActiveSupport, peut être utilisé pour mettre en cache tout objet Ruby sérialisable dans les requêtes.

Pour extraire une valeur du cache pour une clé donnée, utilisez cache.read :

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

Utilisez cache.write pour écrire une valeur dans le cache:

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

Vous pouvez également utiliser cache.fetch pour lire une valeur du cache et éventuellement écrire une valeur par défaut s'il n'y a pas de valeur:

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

La valeur de retour du bloc passé sera attribuée au cache sous la clé donnée, puis renvoyée.

Vous pouvez également spécifier une expiration du cache:

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

Mise en cache de page

Vous pouvez utiliser le joyau ActionPack page_caching pour mettre en cache des pages individuelles. Cela stocke le résultat d'une requête dynamique en tant que fichier HTML statique, qui est utilisé à la place de la demande dynamique lors des requêtes suivantes. Le fichier README contient des instructions de configuration complètes. Une fois configuré, utilisez la méthode de classe caches_page dans un contrôleur pour mettre en cache le résultat d'une action:

class UsersController < ActionController::Base
  caches_page :index
end

Utilisez expire_page pour forcer l'expiration du cache en supprimant le fichier HTML stocké:

class UsersController < ActionController::Base
  caches_page :index

  def index
    @users = User.all
  end

  def create
    expire_page :action => :index
  end
end

La syntaxe de expire_page imite celle de url_for et des amis.

Mise en cache HTTP

Rails> = 3 est livré avec des capacités de mise en cache HTTP prêtes à l'emploi. Cela utilise les en Cache-Control têtes Cache-Control et ETag pour contrôler la durée pendant laquelle un client ou un intermédiaire (tel qu'un CDN) peut mettre en cache une page.

Dans une action de contrôleur, utilisez expires_in pour définir la longueur de la mise en cache pour cette action:

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

Utilisez expires_now pour forcer l'expiration immédiate d'une ressource en cache sur tout client ou intermédiaire en visite:

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

Mise en cache des actions

Comme pour la mise en cache des pages, la mise en cache des actions met en cache toute la page. La différence est que la requête frappe la pile Rails avant que les filtres ne soient exécutés avant que le cache ne soit servi. Il est extrait de Rails à la gem actionpack-action_caching .

Un exemple courant est la mise en cache d'une action nécessitant une authentification:

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

Les options incluent :expires_in , un :expires_in personnalisé :cache_path (pour les actions avec plusieurs routes devant être mises en cache différemment) et :if / :unless pour contrôler quand l'action doit être mise en 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

Lorsque la mise en page a un contenu dynamique, ne mettez en cache que le contenu de l’action en passant la layout: false en layout: false .



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow