【问题标题】:Rails 4.0 expire_fragment/cache expiration not workingRails 4.0 expire_fragment/缓存过期不起作用
【发布时间】:2013-07-01 00:36:17
【问题描述】:

我一直在尝试使用 rails 的缓存功能,但我无法使某些缓存片段过期,尽管它们似乎已过期。使用 rails 教程网站中指出的“俄罗斯娃娃缓存”,我正在使用此配置

<% 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%>    

我在 release_controller.rb 控制器中使外部缓存过期,我使用 expire_fragment("all_available_releases") 使片段过期。我在控制器的每个更新、删除或添加条目的方法中都使用它。

这是 WEBrick 的日志,虽然过期片段被注册,但 5 行后过期片段被读取并使用,而它不应该。这个例子是在销毁调用之后。

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)

我什至尝试过使用Rails.cache.delete("all_available_releases"),但也没有用。

如果我从我的 html.erb 中删除 &lt;%cache "all_available_releases"%&gt;(和一个 &lt;%end%&gt;),缓存会正常工作,并且会随时过期。

【问题讨论】:

    标签: ruby-on-rails ruby caching cache-expiration


    【解决方案1】:

    我认为问题在于,当您在视图中缓存片段时,缓存摘要被添加到缓存键 (views/all_available_releases/41cb0a928326986f35f41c52bb3d8352),但 expire_fragment 没有使用摘要(views/all_available_releases)。

    如果您将skip_digest: true 添加到视图中的缓存调用,它应该会阻止使用摘要。

    <% 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%>
    

    缓存摘要仅适用于自动缓存过期。如果您需要手动使缓存键过期,则不能使用缓存摘要。

    【讨论】:

    • 这给我带来了很多麻烦。谢谢!
    • 谢谢,这是在哪里记录的?
    • 找到了它的引用here
    • 谢谢——我第一次尝试缓存,但我被困了 30 分钟!!
    • 刚遇到同样的问题,完美解决,谢谢!
    【解决方案2】:

    Jbuilder 不支持skip_digest。在经历了许多失败的方法之后,我决定在这里分享我的答案,因为它与上述问题的 Rails 视图高度相关。

    这是一个相关的 Q/问题,其中 DHH 基本上告诉那个人他不能明确地使 fragment_caches 过期。 https://github.com/rails/cache_digests/issues/35 一切都不是方形的,所以这里有一个解决方法:

    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
    

    然后你可以在任何地方明确地过期,比如在观察者中

    class MenuCacheObserver < ActiveRecord::Observer
      observe :menu, :menuitem, :menusubnavigation
    
      def after_save obj
        Rails.cache.delete(:clients)
      end
    end
    

    在某些情况下,这可能是有道理的。一般来说,在大多数情况下,您应该使用缓存输入中的对象,例如 json.cache! @my_object do 包装 jbuilder 视图。这样,当对象上的 updated_at 发生变化时,它就会失效。

    【讨论】:

    • 看起来jbuilder现在支持skip_digest(我使用的是2.4.0)-以下对我有用json.cache! ['v1', my_obj.cache_key], skip_digest: true, expires_in: 6.hours do json.partial! 'path/to/my/partial', obj: my_obj end
    • 不,我正在使用jbuilder (2.6.1),但 skip_digest 不起作用
    【解决方案3】:

    我自己也遇到了这个问题,我处理它的方法是通过正则表达式。它可能不是最优雅的解决方案,但效果很好。

    ActionController::Base.new.expire_fragment(%r{offer_#{@offer.id}/*})
    

    不过,添加 skip_digest 会好很多。

    【讨论】:

      【解决方案4】:

      在 Rails 5 中,我采取了以下步骤来破坏缓存,而不使用 skip_digest: true。我们的问题是更改 I18n 字符串的值不会反映在计算的缓存摘要中,因此缓存不会自动被破坏。

      这是定义缓存块的视图:

      / views/layouts/_footer.html.slim
      - cache :footer do
        span= t('shared.footer')
      

      然后在 rails 控制台我运行:

      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 将根据 virtual_path 关键字参数计算摘要。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-20
        • 2021-05-09
        • 2011-11-08
        • 1970-01-01
        • 2018-05-01
        • 2011-08-19
        • 2011-02-25
        • 1970-01-01
        相关资源
        最近更新 更多