加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 使用模板继承的俄罗斯玩偶缓存的问题

发布时间:2020-12-17 02:04:48 所属栏目:百科 来源:网络整理
导读:我一直在相当复杂的Rails应用程序的选定部分中彼此独立地使用模板继承和俄罗斯娃娃缓存(使用 cache_digests gem),并取得了很大的成功. 我很难以合理的方式使用这两种技术,这让我怀疑自己可能做错了什么…… 对于一个非常简单的示例,请考虑一个由两个控制器Th
我一直在相当复杂的Rails应用程序的选定部分中彼此独立地使用模板继承和俄罗斯娃娃缓存(使用 cache_digests gem),并取得了很大的成功.

我很难以合理的方式使用这两种技术,这让我怀疑自己可能做错了什么……

对于一个非常简单的示例,请考虑一个由两个控制器ThingOnes和ThingTwos组成的应用程序.此应用程序有一个布局(layouts / application.html.erb),它只是呈现一个头文件:<%= render'header'%>.

默认情况下,Rails会查看此部分的一系列位置,包括布局的视图目录(views / application / _header.html.erb)以及当前控制器的任何特定位置(如views / thing_ones / _header). html.erb或views / thing_twos / _header.html.erb).这意味着,出于缓存目的,我基本上有一个模板依赖列表(不计算引擎,或其他任何东西),如下所示:

[
  "application/header","thing_ones/header","thing_twos/header"
]

现在,我们使用缓存来包装该渲染调用,如下所示:

<% cache 'header' do %>
  <%= render 'header' %>
<% end %>

不幸的是,运行rake cache_digests:nested_dependencies TEMPLATE = layouts / application会产生以下依赖项列表.

[
  "layouts/header"
]

它似乎根本不关心模板继承.修改未包含在列表中的文件具有修改未包含在列表中的文件的预期效果 – 缓存未正确过期并且显示过时标头.

通过指定相关的模板路径可以轻松地进行重新设置,如下所示:

<% cache 'header' do %>
  <%# Template Dependency: application/header %>
  <%# Template Dependency: thing_ones/header %>
  <%# Template Dependency: thing_twos/header %>
  <%= render 'header' %>
<% end %>

这似乎是一个非常糟糕的解决方案,因为它不能很好地生长,并且需要大量无聊的装饰来缓存调用以保留现有的模板继承行为.

同样,可以更明确地指定标头位置,如下所示:

<% cache 'header' do %>
  <%= render 'application/header' %>
<% end %>

这也无法保留现有的模板继承行为,使其不适合我们的需求.

最后一个选择在于将缓存调用移动到头部分本身.这不仅效率低下,因为它将渲染调用从缓存中移除.它也比DRY更加WET(写两次),这是一个很大的转折点.

所以,要了解我的实际问题……我这样做是否正确?这似乎是一个相当大的缺点,会影响各种各样的实现,但我真的找不到与此特定问题相关的大量讨论,所以我想知道其他人是否以更好的方式来做这件事.有没有更好的方法来执行此操作,或者至少自动为部分渲染指定整个模板依赖关系层次结构?

解决方法

这里的问题实际上是你最后建议的:你必须将缓存方法移动到渲染模板中.

这可能看起来像更多的代码,但这是缓存摘要正常工作的必要条件.此外,如果您的partials(application,thing_ones和thing_twos中的_header.html.erb)不同,缓存键也应该不同.这意味着你应该得到这样的东西:

# layouts/application.html.erb
<%= render 'header' %>

# application/_header.html.erb 
<% cache 'application_header' do %>
  ...
<% end %>

# thing_ones/_header.html.erb
<% cache 'thing_ones_header' do %>
  ...
<% end %>

# and thing_twos/_header.html.erb
<% cache 'thing_twos_header' do %>
  ...
<% end %>

如果没有不同的缓存键,这些缓存将相互覆盖,这意味着如果例如. application / _header.html.erb首先被缓存,然后是一个呈现一个ThingOnes和ThingTwos页面的那个.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读