ruby-on-rails - rails 5.2 cache
Rails 4.0 expire_fragment/cache expiration no funciona (4)
Acabo de toparme con este tema y la forma en que me acerqué a tratarlo fue a través de expresiones regulares. Puede que no sea la solución más elegante, pero funciona bien.
ActionController::Base.new.expire_fragment(%r{offer_#{@offer.id}/*})
Sin embargo, agregar el skip_digest es mucho más agradable.
He intentado usar las capacidades de almacenamiento en caché de los rieles, pero no puedo caducar ningún fragmento de caché, aunque parecen caducar. Usando el ''Caché de Muñeca Rusa'' como se señala en el sitio tutorial Rails, estoy usando esta configuración
<% cache "all_available_releases" do %>
<% @releases.each do |release| %>
<% cache(release) do %>
<html code with>
<%ruby code @release.name blah blah blah%>
<%end%>
<%end%>
<%end%>
Venzo el almacenamiento en caché externo en el controlador de release_controller.rb, donde utilizo expire_fragment ("all_available_releases") para caducar el fragmento. Lo uso en todos los métodos del controlador que actualiza o elimina o agrega una entrada.
Este es el registro de WEBrick, donde si bien el fragmento de expiración se registra, 5 líneas más tarde el fragmento caducado se lee y se utiliza mientras que no debería. Este ejemplo es después de una llamada de destrucción.
Processing by ReleasesController#destroy as HTML
Parameters: {"authenticity_token"=>"***/***/********************+********=", "id"=>"2"}
Release Load (0.1ms) SELECT "releases".* FROM "releases" WHERE "releases"."id" = ? LIMIT 1 [["id", "2"]]
(0.1ms) begin transaction
SQL (2.0ms) DELETE FROM "releases" WHERE "releases"."id" = ? [["id", 2]]
(148.0ms) commit transaction
Expire fragment views/all_available_releases (0.1ms)
Redirected to http://127.0.0.1:3000/releases
Completed 302 Found in 180ms (ActiveRecord: 150.2ms)
Started GET "/releases" for 127.0.0.1 at 2013-07-03 13:09:51 +0300
Processing by ReleasesController#index as HTML
Read fragment views/all_available_releases/41cb0a928326986f35f41c52bb3d8352 (0.1ms)
Rendered releases/index.html.erb within layouts/application (0.6ms)
Completed 200 OK in 5ms (Views: 4.0ms | ActiveRecord: 0.0ms)
Incluso intenté usar Rails.cache.delete("all_available_releases")
y tampoco funcionó.
si <%cache "all_available_releases"%>
(y uno <%end%>
) de mi html.erb, el almacenamiento en caché funciona bien y expira cada vez que debería.
Creo que el problema es que cuando almacena en caché el fragmento en su vista, se agrega un resumen de caché a la clave de caché (views / all_available_releases / 41cb0a928326986f35f41c52bb3d8352 ), pero expire_fragment no usa el resumen (views / all_available_releases).
Si agrega skip_digest: true
a la llamada de caché en la vista, debe evitar que se use el resumen.
<% cache "all_available_releases", skip_digest: true do %>
<% @releases.each do |release| %>
<% cache(release) do %>
<html code with>
<%ruby code @release.name blah blah blah%>
<%end%>
<%end%>
<%end%>
Los resúmenes de caché solo están destinados a ser utilizados con caducidad automática de caché. Si necesita caducar manualmente las claves de caché, entonces no puede usar los resúmenes de caché.
En Rails 5 di los siguientes pasos para reventar el caché sin recurrir a skip_digest: true
. Nuestro problema era que cambiar el valor de las cadenas I18n no se refleja en el resumen de caché calculado, por lo que la caché no se eliminaría automáticamente.
Aquí está la vista donde se define el bloque de caché:
/ views/layouts/_footer.html.slim
- cache :footer do
span= t(''shared.footer'')
Luego en la consola Rails corro:
fragment = ActionController::Base.new.view_context.cache_fragment_name(:footer, virtual_path: ''layouts/_footer.html.slim'')
ActionController::Base.new.expire_fragment(fragment)
cache_fragment_name
resolverá el resumen basado en el argumento de la palabra clave virtual_path
.
Jbuilder no es compatible con skip_digest. Después de muchos enfoques fallidos, decidí compartir mis respuestas aquí, ya que está muy relacionado, aunque no con una vista de rieles, como es el problema anterior.
Aquí hay un Q / issue relacionado en el que DHH básicamente le dice al chico que no puede caducar fragment_caches explícitamente. https://github.com/rails/cache_digests/issues/35 Todo no es cuadrado, así que aquí hay una forma de evitar esto:
class MenuController
def index
json = Rails.cache.fetch(''clients'') do
@items = Menu.all
render_to_string( template: ''menu/index'', locals: {items: @items})
end
render json: json
end
end
entonces puedes caducar explicitamente esto en cualquier lugar, como en un observador
class MenuCacheObserver < ActiveRecord::Observer
observe :menu, :menuitem, :menusubnavigation
def after_save obj
Rails.cache.delete(:clients)
end
end
En algunos casos esto puede tener sentido. En general, en la mayoría de los casos, debería usar el objeto en la entrada de la memoria caché, ¡como json.cache! @my_object do
json.cache! @my_object do
envolver la vista jbuilder. De esta forma, se invalidará cuando se actualice updated_at en el objeto.