Ruby on Rails
Almacenamiento en caché
Buscar..
Muñeca rusa caching
Es posible que desee anidar fragmentos en caché dentro de otros fragmentos en caché. Esto se llama Russian doll caching
.
La ventaja del Russian doll caching
de Russian doll caching
es que si se actualiza un solo producto, todos los demás fragmentos internos se pueden reutilizar cuando se regenera el fragmento exterior.
Como se explicó en la sección anterior, un archivo almacenado en caché caducará si el valor de updated_at
cambia para un registro del cual depende directamente el archivo almacenado en caché. Sin embargo, esto no caducará ningún caché en el que esté anidado el fragmento.
Por ejemplo, tome la siguiente vista:
<% cache product do %>
<%= render product.games %>
<% end %>
Que a su vez hace que esta vista:
<% cache game do %>
<%= render game %>
<% end %>
Si se cambia algún atributo del juego, el valor updated_at
se establecerá en la hora actual, con lo que caducará el caché.
Sin embargo, dado que updated_at
no se modificará para el objeto del producto, esa memoria caché no caducará y su aplicación servirá datos obsoletos. Para solucionar esto, unimos los modelos con el método táctil:
class Product < ApplicationRecord
has_many :games
end
class Game < ApplicationRecord
belongs_to :product, touch: true
end
SQL Caching
El almacenamiento en caché de consultas es una característica de Rails
que almacena en caché el conjunto de resultados devuelto por cada consulta. Si Rails
vuelve a encontrar la misma consulta para esa solicitud, usará el conjunto de resultados en caché en lugar de ejecutar la consulta nuevamente en la base de datos.
Por ejemplo:
class ProductsController < ApplicationController
def index
# Run a find query
@products = Product.all
...
# Run the same query again
@products = Product.all
end
end
La segunda vez que se ejecuta la misma consulta en la base de datos, en realidad no llegará a la base de datos. La primera vez que se devuelve el resultado de la consulta, se almacena en el caché de consulta (en la memoria) y la segunda vez se extrae de la memoria.
Sin embargo, es importante tener en cuenta que los cachés de consulta se crean al inicio de una acción y se destruyen al final de esa acción y, por lo tanto, persisten solo durante la duración de la acción. Si desea almacenar los resultados de la consulta de una manera más persistente, puede hacerlo con el almacenamiento en caché de bajo nivel.
Almacenamiento en caché de fragmentos
Rails.cache
, proporcionado por ActiveSupport, puede usarse para almacenar en caché cualquier objeto Ruby serializable en todas las solicitudes.
Para obtener un valor de la memoria caché para una clave dada, use cache.read
:
Rails.cache.read('city')
# => nil
Use cache.write
para escribir un valor en el caché:
Rails.cache.write('city', 'Duckburgh')
Rails.cache.read('city')
# => 'Duckburgh'
Alternativamente, use cache.fetch
para leer un valor del caché y, opcionalmente, escriba un valor predeterminado si no hay ningún valor:
Rails.cache.fetch('user') do
User.where(:is_awesome => true)
end
El valor de retorno del bloque pasado se asignará a la memoria caché bajo la clave dada, y luego se devolverá.
También puede especificar un vencimiento de caché:
Rails.cache.fetch('user', :expires_in => 30.minutes) do
User.where(:is_awesome => true)
end
Almacenamiento en caché de páginas
Puede usar la gema page_caching de ActionPack para almacenar en caché páginas individuales. Esto almacena el resultado de una solicitud dinámica como un archivo HTML estático, que se sirve en lugar de la solicitud dinámica en solicitudes posteriores. El archivo README contiene instrucciones de configuración completas. Una vez configurado, use el método de clase caches_page
en un controlador para almacenar en caché el resultado de una acción:
class UsersController < ActionController::Base
caches_page :index
end
Utilice expire_page
para forzar la caducidad de la memoria caché eliminando el archivo HTML almacenado:
class UsersController < ActionController::Base
caches_page :index
def index
@users = User.all
end
def create
expire_page :action => :index
end
end
La sintaxis de expire_page
imita la de url_for
y friends.
Almacenamiento en caché HTTP
Rails> = 3 viene con capacidades de almacenamiento en caché HTTP fuera de la caja. Esto utiliza los encabezados Cache-Control
y ETag
para controlar cuánto tiempo un cliente o intermediario (como un CDN) puede almacenar en caché una página.
En una acción de controlador, use expires_in
para establecer la duración del almacenamiento en caché para esa acción:
def show
@user = User.find params[:id]
expires_in 30.minutes, :public => true
end
Utilice expires_now
para forzar la expiración inmediata de un recurso en caché en cualquier cliente o intermediario visitante:
def show
@users = User.find params[:id]
expires_now if params[:id] == 1
end
Almacenamiento en caché de acciones
Al igual que el almacenamiento en caché de páginas, el almacenamiento en caché de acciones almacena en caché toda la página. La diferencia es que la solicitud llega a la pila de Rails, por lo que antes de que se ejecuten los filtros antes de que se sirva el caché. Se extrae de Rails a la gema actionpack-action_caching .
Un ejemplo común es el almacenamiento en caché de una acción que requiere autenticación:
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
Las opciones incluyen :expires_in
, un custom :cache_path
(para acciones con múltiples rutas que deben almacenarse en caché de manera diferente) y :if
/ :unless
que se controle cuándo se debe almacenar en caché la acción.
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
Cuando el diseño tiene contenido dinámico, almacene en caché solo el contenido de la acción pasando el layout: false
.