`
liguokai
  • 浏览: 659 次
  • 来自: ...
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

RailCast episode 172 - Touch and Cache (翻译)

阅读更多
Rails近期升级到了2.3.3版。尽管这次只是一次较小的升级,主要是对之前版本的一些错误修正(bug fixes), 这个新版本还是给我们提供了一些新的特性(features)。Touch就是其中的一个。我们将在这集为大家展现如何使用touch去改进你的应用程序中的缓存。

如果你还没有升级rails到2.3.3,你可以在命令行运行:

<commandline>sudo gem update rails</commandline>

升级到新版本. 然后你可以在任何你想升级的应用程序里面修改/config/enrionment.rb文件的最上面一行:

   1. # Specifies gem version of Rails to use when vendor/rails is not present  
   2. RAILS_GEM_VERSION = '2.3.3' unless defined? RAILS_GEM_VERSION  


如果你准备升级一个应用程序,请确保该应用程序有个优秀的测试套件(test suite)。 这样你可以保证该升级不会对破坏你原有的应用程序。

与片段缓存(Fragment Caching)一起使用touch
  
以下显示的是一个博客应用程序的article页面。这个页面的流量很大,所以我们想要改进他的性能。



我们可以添加片段缓存(Fragment Caching)去缩短页面的相应时间。这个可能不是最理想的解决方案,但它却能让我们快速的解决问题。我们先对这个页面应用片段缓存(Fragment Caching)看看回是怎么样。

在开发模式下,缓存(caching)是默认被禁用的。应此我们先要打开缓存。我们需要修改/config/environments/default.rb文件:

config.action_controller.perform_caching = true


另一种方式是创建一个临时环境(staging environment). 如果你想了解更多关于如何创建临时环境(staging envrionment),你可以查看第72集. 如果你创建了一个临时环境(staging environment),你就不需要在你的开发环境里面激活或禁用缓存(caching)。

片段缓存(fragment caching)将会添加在article的show视图内。视图代码如下:

<% title @article.name %>  
<p class="author"><em>from <%=h @article.author_name %></em></p>  
<%= simple_format @article.content %>  
<p><%= link_to "Back to Articles", articles_path %></p>  
<% unless @article.comments.empty? %>  
  <h2><%= pluralize(@article.comments.size, 'comment') %></h2>  
  <div id="comments">  
  <% for comment in @article.comments %>  
    <div id="comment">  
      <strong><%= link_to_unless comment.site_url.blank?, h(comment.author_name), h(comment.site_url) %></strong>  
      <em>on <%= comment.created_at.strftime('%b %d, %Y at %H:%M') %></em>  
      <%= simple_format comment.content %>  
    </div>  
  <% end %>  
  </div>  
<% end %>  
<h3>Add your comment:</h3>  
<%= render :partial => 'comments/form' %>  


我们调用cache方法并把要缓存的片段包含在缓存块内:

<% title @article.name %>  
<% cache @article do %>  
  <p class="author"><em>from <%=h @article.author_name %></em></p>  
  <!-- Rest of code omitted -->  
<% end %>  
<h3>Add your comment:</h3>  
<%= render :partial => 'comments/form' %>  



cache方法接受一个可选参数。这个参数被用作缓存的key(默认情况下,页面的URL会被作为缓存的key)。如果我们把模型(model)当作参数,那么模型的cache_key属性将被作为这个key。这就是说,当article更新的时候这个缓存片段就会过期。我们可以在控制台(console)里面演示:

<commandline>
>> a = Article.first
=> #<Article id: 1, name: "The Piano, a Marvellous Instrument", content: "The piano is a musical instrument played by means o...", author_name: "Billy Belmer", created_at: "2009-06-14 19:39:40", updated_at: "2009-07-29 19:14:17">
>> a.cache_key
=> "articles/1-20090729191417"
</commandline>

cache_key由模型(model)名,模型的id和updated_at属性组成。key的最后一段非常有用,因为这一段组成部分,这个key每次都会应为模型的更新而改变。这样每次模型的任意属性有更改,这个缓存片段都会过期。

我们通过刷新2次我们的article页面来演示缓存。在development.log里面我们可以看到:

<commandline>
  Processing ArticlesController#show (for 127.0.0.1 at 2009-07-30 20:22:30) [GET]
    Parameters: {"id"=>"1"}
    Article Load (0.2ms)   SELECT * FROM "articles" WHERE ("articles"."id" = 1)
  Rendering /Users/eifion/rails/apps_for_asciicasts/ep172/app/views/articles/show.html.erb
  Cached fragment hit: views/articles/1-20090729225258 (0.0ms)
    SQL (0.2ms)   SELECT count(*) AS count_all FROM "comments" WHERE ("comments".article_id = 1)
    CACHE (0.0ms)   SELECT count(*) AS count_all FROM "comments" WHERE ("comments".article_id = 1)
    Comment Load (0.3ms)   SELECT * FROM "comments" WHERE ("comments".article_id = 1)
  Cached fragment miss: views/articles/1-20090729225258 (0.0ms)

  Processing ArticlesController#show (for 127.0.0.1 at 2009-07-30 20:22:45) [GET]
    Parameters: {"id"=>"1"}
    Article Load (0.2ms)   SELECT * FROM "articles" WHERE ("articles"."id" = 1)
  Rendering /Users/eifion/rails/apps_for_asciicasts/ep172/app/views/articles/show.html.erb
  Cached fragment hit: views/articles/1-20090729225258 (0.0ms)
</commandline>

第一次加载页面的时候,因为缓存内没有该key对应的缓存片段,所以找不到对应的缓存片段(cached fragment)。这时数据就会从数据库里面取出来,并创建缓存。第二次加载页面的时候对应该key的缓存片段被找到,这时我们就不需要从数据库里面读取数据。

如果我们编辑article,比如修改标题,这个缓存片段会自动失效并且页面被更新。这时因为当我们更新article的时候,模型(model)的updated_at属性也被修改,模型的cache_key也应此而更新。



使用Touch

我们现在所有的改动都应该能在早期版本的rails上面工作。那么touch是怎么工作的呢?我们将从touch如何在控制台(console) 下面工作开始讲起:

我们首先取得第一个article并找到它的updated_at属性。

<commandline>
>> a = Article.first
=> #<Article id: 1, name: "The Piano, a Beautiful Instrument.", content: "The piano is a musical instrument played by means o...", author_name: "Billy Belmer", created_at: "2009-06-14 19:39:40", updated_at: "2009-07-29 20:27:34">
>> a.updated_at
=> Wed, 29 Jul 2009 22:27:34 UTC +00:00
</commandline>

如果我们对article调用touch方法,那么它的updated_at属性也会被修改。

<commandline>
>> a.touch
=> true
>> a.updated_at
=> Wed, 29 Jul 2009 22:27:53 UTC +00:00
</commandline>

这就是touch。当model调用touch方法,model就会修改它的updated_at属性值为现在的时间。这看起来不像个特别有用的方法,但当用在associations时touch方法就会显示出它的价值。

在我们的应用程序里一个Article可能有很多Comments。如果我们使用article页面的表单对article添加一条comment,这条comment将不会作为article页面的一部分被显示。这是因为article已经被缓存了,article页面只会显示缓存里面的comments。当一条comment被添加时article的时间戳未被修改,所以缓存片段不会过期。

要想实现当添加或修改comment时article页面显示新的comment,我们仅仅需要对comment模型(model)做一点点修改:

class Comment < ActiveRecord::Base  
  belongs_to :article, :touch => true  
end  


给belongs_to关系添加 :touch => true 意味着当创建,更新或者删除一条comment的时候,该comment属于(belongs_to)的article被touched。现在我们添加一条comment,缓存会失效并且页面会更新而且显示刚添加的comment。



这项技术不仅限在片段缓存(fragment caching)上使用。touch也能很好的和Memcached工作,当新缓存创建时Memcached会自动清除旧缓存。不需要使用sweepers更不需要去写一堆sweepers需要的多余代码。
分享到:
评论

相关推荐

    Android代码-安卓部分小控件

    Learn way of android in default way: API 7 : Android 2.1(Eclair) Tools: Android Studio JAVA: java version "1.7.0_80" Java(TM) SE Runtime Environment ...episode 8 -- Catch call event and update call l

    Episode-Based Prototype Generating Network for Zero-Shot Learnin

    在"Episode-Based Prototype Generating Network for Zero-Shot Learning"这篇论文中,作者提出了一种新的训练框架,用于解决零样本学习(ZSL)中的挑战。这个框架基于episode训练,每个episode模拟一个零样本分类...

    IMDb Hide Episode Spoilers-crx插件

    版本更改(https://github.com/SIlver--/IMDb-Hide-Episode-Spoilers)版本1.4-已更新,可与@swstraus版本1.3的HTTPS imdb配合使用-已在季节情节列表和情节页面上添加了隐藏剧透1.2-在角色和角色页面上添加了隐藏剧...

    Intro to Graph Databases Episode #3 - Property Graph Model.mp4

    Intro to Graph Databases Episode #3 - Property Graph Model.mp4

    evangelion-episode-generator-main

    标题“evangelion-episode-generator-main”显然与日本著名动画《新世纪福音战士》(Neon Genesis Evangelion)有关,这是一部在90年代末期播出的极具影响力的作品,以其深奥复杂的剧情和心理描写闻名。这个项目可能...

    Intro to Graph Databases Episode #5 - Cypher, the Graph Query La

    Intro to Graph Databases Episode #5 - Cypher, the Graph Query Language.mp4

    hackerwars-episode-3:HOME†QUEST(儿童的ToDo应用)DIT

    HOME†QUEST 待办事项为孩子的应用程序。特征填写此空白入门git clone ...bundle exec rackup 首页搜寻注册: : 任务列表: 创建任务: 奖励列表: 创建奖励: 用于API测试Swagger用户界面: swagger.yaml: 库/框架...

    Intro to Graph Databases Episode #6 - Continuing with Cypher.mp4

    Intro to Graph Databases Episode #6 - Continuing with Cypher.mp4

    Intro to Graph Databases Episode #2 - Properties of Graph DBs &

    Intro to Graph Databases Episode #2 - Properties of Graph DBs & Use Cases.mp4

    Crunchyroll New Episode Highlighter-crx插件

    Crunchyroll New Episode Highlighter完全按照其说的去做; 它突出显示了在您查看页面的同一天发布了新剧集的节目。 如果您跟随几个Crunchyroll联播并想赶上一天中的所有新节目,则此功能特别有用。 免责声明:这是...

    Netflix AutoSkip:Skip Intro&Next Episode「Netflix AutoSkip: Skip Intro & Next Episode」-crx插件

    Netflix自动跳过介绍和自动播放下一集。 用于“ Netflix狂欢观看”的基本应用程序! -直接跳过简介和概述,而无需单击跳过按钮。 -直接播放而无需等待下一集。 --- 3.1版本-间歇性错误修复。 (跳过后停止)-3.0版本...

    Intro to Graph Databases Episode #4 - (RDBMS+SQL) to (Graphs+Cyp

    Intro to Graph Databases Episode #4 - (RDBMS+SQL) to (Graphs+Cypher).mp4

    Shush Episode Navigator-crx插件

    语言:English 在Shush.tv上更改剧集,而无需返回到剧集列表 一个小的扩展程序,在shush.tv的所有视频下添加了“上一个”和“下一个”链接,这比在情节列表中查找要容易一些。 扩展程序非常基本,不会检测到“上一集...

    My Episode Guide-crx插件

    语言:English 播放下一个节目,供您选择的电视节目播放。 ... 摘要此扩展程序使您可以将所有喜欢的电视节目收集到一个地方。 您可以轻松浏览节目列表,并查看每部节目的下一集何时播出。 总是可以看到的日间计数器显示...

    Anime episode tracker-crx插件

    语言:English 追踪您正在观看的动漫最新剧集 如果您经常忘记在特定动漫上观看的最后一集是什么,请获取此扩展名。 它会保存您观看的每个动画的最新剧集,您可以轻松返回该剧集并继续观看。 *注意:目前仅适用于...

    Hulu Random Episode Button-crx插件

    语言:English 此扩展将随机集中按钮添加到hulu。 它是如何工作的: 1.安装扩展名。 2.... 在“剧集”旁边,您应该看到“随机集”按钮。 3.... 它应该看起来像两个双胞胎箭头。 单击它,您也可以从那里切换到随机集中。...

    Seen! Tv Series Episode Tracker-crx插件

    语言:English 追踪您最喜欢的电视节目的最聪明和最明确的方式!看到的剧集!看到了!帮助您以最智能和最快的方式追踪您最喜欢的电视节目的最后一集。seen!为您提供机会,不仅可以轻松地浏览您的电视节目剧集,而是...

    Torrent Links for Episode Calendar-crx插件

    语言:English (UK) 几乎即时的磁力链接,使用Torrent网站根据您的喜好查找链接。 这将为您提供情节日历中每个剧集的海盗湾磁铁链接,并提供获取不同质量链接的选项,您还可以下载所有未观看的链接。...

Global site tag (gtag.js) - Google Analytics