Rails 如何将网页标题也塞进缓存?

lukefan · 2015年08月31日 · 最后由 lukefan 回复于 2015年09月04日 · 2826 次阅读

我有一段代码如下:

<% cache [:resource, @page.id.to_s] do %>
<% content_for :title do %>
<title><%=@page.title %></title>
<% end %>

第一次跑的时候,没有问题。但是缓存之后,标题就变成了 undefined。 于是只能改成这样,把标题的部分放在混存外面,每次刷新页面,其他都缓存了,但是 title 还是需要去读数据库,很不爽。

<% content_for :title do %>
<title><%=@page.title %></title>
<% end %>
<% cache [:resource, @page.id.to_s] do %>

有什么办法吗?

不读数据库怎么找到 @page

代码嵌套错误,cache 放里面。

#1 楼 @rei 其他部分都 cache 了,不再需要@page。 但是 title 缓存有问题。

#3 楼 @lukefan title需要@page #4 楼 @lukefan 放到 cache 里面

#3 楼 @lukefan 那还要把 cache_key 改成 cache [:resource, params[:id]],并且无法利用 digest key 了。

<% content_for :title do %>
  <% cache [:resource, @page.id, :title] do %>
    <title><%=@page.title %></title>
  <% end %>
<% end %>

但是在 cache key 的地方已经读了一次 @page 了,缓存一个 title 意义不大。并且@page.id 做 key 没有利用到 digest key。

#7 楼 @rei 我将代码按照你说的调整了。

<% content_for :title do %>
<% cache [:resource, params[:id], :title] do %>
    <title><%=@page.simple_title %></title>
  <% end %>
<% end %>
<% cache [:resource, params[:id]] do %>
<table class="table table-striped">

但是,每次刷新页面,依然需要读取数据库。

#8 楼 @lukefan 1. action 里面有没有查询 @page 2. 开发环境没有开片段缓存。

其实我的意思是,正常状况下 @page 怎么都要查一次的。

我明白了,楼主的意思难道是希望做完全静态化。 这样的话,你要把页面 cache 下来,存为 HTML 文件,放在 nginx 可以访问到的路径下。 不过,除非非常大规模的应用,否则没必要完全不读数据库的全静态化。大规模应用的话,这一步也不应该自己来做,而是交给 CDN 做,只要设定哪些页面由 CDN 静态化缓存即可。

#9 楼 @rei 我最后把@page的读取,也从 action 里面移出来了。 终于不读数据库了。 按道理来说,不应该这样。 在列表 action 里面,@pages的读取也是在 action 里面,就没有遇到这种问题。

#10 楼 @kgen cache_page 确实可以将页面完全静态化成为 html。 但是使用这种模式,对于那些需要登陆的网页来说,就是一个灾难。 完全静态化,登陆也就完蛋了。

#11 楼 @lukefan 返回复数结果的查询是延迟查询,实际取结果的时候才执行(例如调用 each)。

再提醒下,现在这个缓存内容变更了需要手动过期。

#13 楼 @rei 非常感谢。

expire_fragment(%r{resource/[/s/S]*?})

我现在的 cache 失效策略,是在出现更新的时候,很粗暴的一次性干掉所有 cache。 当然,也可以很精细的逐条处理,不过 cache 失效对于我的项目来说,是个小概率事件。 而且,我很讨厌处理那些由于失效策略失败所引发的问题,很难定位。

#12 楼 @lukefan 一些流量很大的网站,比如新闻站,会静态化为 html,他们大部分时候不需要登录功能。 其实,完全静态化,登录功能还是可以做的,通过 AJAX 方式请求那个区块,比如一些电商站就是这么做的。

楼主,不要太强迫症哦!

#16 楼 @cys 确实有些强迫症。 经常在网站完全没有用户的时候,写这种处理每秒几千上万并发时才需要的东西。 我现在写这些东西,基本上都是业余爱好了,所以就任性一下吧。

#15 楼 @kgen 确实,可以通过纯 js 的方式来搞之部分。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号