es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Caché de Rails (una vez más)

Tengo una base de datos de películas con películas, géneros, estudios, actores y algunos otros modelos.

El pie de página del sitio web siempre debe mostrar algo como “la base de datos contiene x películas (y estudios) con z géneros y a actores”.
Como no quiero ir y hacer “Movie.count”, “Actor.count”, etc. en cada actualización de página, quiero guardar en caché los valores y actualizarlos solo si se agrega o destruye una película / actor, etc.

Pensé en crear un método en el controlador de la aplicación que haga algo como lo siguiente (y luego se llame “beforeaction” en toda la aplicación), pero eso no funciona – obtuve un error que dice “método desconocido ‘cachekeywithversion’, parece que este método es un método de ActiveRecord, no de ActiveController.

Pensé brevemente en usar variables de sesión para almacenar estos valores, pero eso parece ir en contra del diseño.

Mi método de controlador de borrador (que causó el error mencionado anteriormente):

def footer_cache
@footer_movies = Rails.cache.fetch(“#{cache_key_with_version}/sum_movies”, expires_in: 12.hours) do
Movie.count
end
@footer_genres = Rails.cache.fetch(“#{cache_key_with_version}/sum_genres”, expires_in: 12.hours) do
Genre.count
end
@footer_studios = Rails.cache.fetch(“#{cache_key_with_version}/sum_studios”, expires_in: 12.hours) do
Studio.count
end
@footer_actors = Rails.cache.fetch(“#{cache_key_with_version}/sum_actors”, expires_in: 12.hours) do
Actor.count
end
end

¿Qué me falta?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Parece que el método cache_key_with_version es un método de ActiveRecord y no está disponible en ApplicationController. Para resolver este problema, puedes intentar agregar un prefijo al clave de caché con una cadena que represente la versión de la aplicación, por ejemplo:

    Rails.cache.fetch("v1/sum_movies", expires_in: 12.hours) do
      Movie.count
    end
    

    Al agregar un prefijo de versión a la clave de caché, te aseguras de que la caché se actualice cuando se actualice la aplicación, evitando la necesidad de llamar a cache_key_with_version.

    Otra cosa a considerar es utilizar un cache sweeper para expirar automáticamente la caché cuando se agrega o se elimina un registro. Puedes definir una clase de cache sweeper y llamarla con el callback before_action:

    class MoviesSweeper < ActionController::Caching::Sweeper
      observe Movie
    
      def after_create(movie)
        expire_cache
      end
    
      def after_destroy(movie)
        expire_cache
      end
    
      private
    
      def expire_cache
        Rails.cache.delete("v1/sum_movies")
        Rails.cache.delete("v1/sum_genres")
        Rails.cache.delete("v1/sum_studios")
        Rails.cache.delete("v1/sum_actors")
      end
    end
    
    class ApplicationController < ActionController::Base
      before_action :footer_cache
      cache_sweeper :movies_sweeper
    
      def footer_cache
        @footer_movies = Rails.cache.fetch("v1/sum_movies", expires_in: 12.hours) do
          Movie.count
        end
        @footer_genres = Rails.cache.fetch("v1/sum_genres", expires_in: 12.hours) do
          Genre.count
        end
        @footer_studios = Rails.cache.fetch("v1/sum_studios", expires_in: 12.hours) do
          Studio.count
        end
        @footer_actors = Rails.cache.fetch("v1/sum_actors", expires_in: 12.hours) do
          Actor.count
        end
      end
    end
    

    En este ejemplo, la clase MoviesSweeper observa el modelo Movie y expira la caché cuando se crea o se elimina un nuevo registro. El callback cache_sweeper se llama en ApplicationController para registrar la clase sweeper.

    ¡Espero que esto sea de ayuda!

Comments are closed.