--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Caching with Rails: An overview</title>
+ <!--[if lt IE 8]>
+ <script src="http://ie7-js.googlecode.com/svn/version/2.0(beta3)/IE8.js" type="text/javascript"></script>
+ <![endif]-->
+ <link href="stylesheets/base.css" media="screen" rel="Stylesheet" type="text/css" />
+ <link href="stylesheets/forms.css" media="screen" rel="Stylesheet" type="text/css" />
+ <link href="stylesheets/more.css" media="screen" rel="Stylesheet" type="text/css" />
+ <style type="text/css">
+ div#container {
+ max-width: 900px;
+ padding-bottom: 3em;
+}
+
+div#content {
+ margin-left: 200px;
+}
+
+div#container.notoc {
+ max-width: 600px;
+}
+
+.notoc div#content {
+ margin-left: 0;
+}
+
+pre {
+ line-height: 1.4em;
+}
+
+#content p tt {
+ background: #eeeeee;
+ border: solid 1px #cccccc;
+ padding: 3px;
+}
+
+dt {
+ font-weight: bold;
+}
+
+#content dt tt {
+ font-size: 10pt;
+}
+
+dd {
+ margin-left: 3em;
+}
+
+#content dt tt, #content pre tt {
+ background: none;
+ padding: 0;
+ border: 0;
+}
+
+#content .olist ol {
+ margin-left: 2em;
+}
+
+#header {
+ position: relative;
+ max-width: 840px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+#header.notoc {
+ max-width: 580px;
+}
+
+#logo {
+ position: absolute;
+ left: 10px;
+ top: 10px;
+ width: 110px;
+ height: 140px;
+}
+
+div#header h1#site_title {
+ background: url('images/ruby_on_rails_by_mike_rundle2.gif') top left no-repeat;
+ position: absolute;
+ width: 392px;
+ height: 55px;
+ left: 145px;
+ top: 20px;
+ margin: 0;
+ padding: 0;
+}
+
+#site_title span {
+ display: none;
+}
+
+#site_title_tagline {
+ display: none;
+}
+
+ul#navMain {
+ position: absolute;
+ margin: 0;
+ padding: 0;
+ top: 97px;
+ left: 145px;
+}
+
+.left-floaty, .right-floaty {
+ padding: 15px;
+}
+
+.admonitionblock,
+.tableblock {
+ margin-left: 1em;
+ margin-right: 1em;
+ margin-top: 0.25em;
+ margin-bottom: 1em;
+}
+
+.admonitionblock .icon {
+ padding-right: 8px;
+}
+
+.admonitionblock .content {
+ border: solid 1px #ffda78;
+ background: #fffebd;
+ padding: 10px;
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+
+.admonitionblock .title {
+ font-size: 140%;
+ margin-bottom: 0.5em;
+}
+
+.tableblock table {
+ border: solid 1px #aaaaff;
+ background: #f0f0ff;
+}
+
+.tableblock th {
+ background: #e0e0e0;
+}
+
+.tableblock th,
+.tableblock td {
+ padding: 3px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+.sidebarblock {
+ margin-top: 0.25em;
+ margin: 1em;
+ border: solid 1px #ccccbb;
+ padding: 8px;
+ background: #ffffe0;
+}
+
+.sidebarblock .sidebar-title {
+ font-size: 140%;
+ font-weight: 600;
+ margin-bottom: 0.3em;
+}
+
+.sidebarblock .sidebar-content > .para:last-child > p {
+ margin-bottom: 0;
+}
+
+.sidebarblock .sidebar-title a {
+ text-decoration: none;
+}
+
+.sidebarblock .sidebar-title a:hover {
+ text-decoration: underline;
+}
+
+ </style>
+</head>
+<body>
+ <div id="header" >
+ <div id="logo">
+ <a href="index.html" title="Ruby on Rails"><img src="images/rails_logo_remix.gif" alt="Rails" height="140" width="110" /></a>
+ </div>
+
+ <h1 id="site_title"><span>Ruby on Rails</span></h1>
+ <h2 id="site_title_tagline">Sustainable productivity for web-application development</h2>
+
+ <ul id="navMain">
+ <li class="first-child"><a href="http://www.rubyonrails.org/" title="Ruby on Rails" class="ruby_on_rails">Ruby on Rails</a></li>
+ <li><a class="manuals" href="index.html" title="Manuals Index">Guides Index</a></li>
+ </ul>
+ </div>
+
+ <div id="container">
+
+ <div id="sidebar">
+ <h2>Chapters</h2>
+ <ol>
+ <li>
+ <a href="#_basic_caching">Basic Caching</a>
+ <ul>
+
+ <li><a href="#_page_caching">Page Caching</a></li>
+
+ <li><a href="#_action_caching">Action Caching</a></li>
+
+ <li><a href="#_fragment_caching">Fragment Caching</a></li>
+
+ <li><a href="#_sweepers">Sweepers</a></li>
+
+ <li><a href="#_sql_caching">SQL Caching</a></li>
+
+ <li><a href="#_cache_stores">Cache stores</a></li>
+
+ </ul>
+ </li>
+ <li>
+ <a href="#_advanced_caching">Advanced Caching</a>
+ </li>
+ </ol>
+ </div>
+
+ <div id="content">
+ <h1>Caching with Rails: An overview</h1>
+ <div id="preamble">\r
+<div class="sectionbody">\r
+<div class="para"><p>Everyone caches. This guide will teach you what you need to know about\r
+avoiding that expensive round-trip to your database and returning what you\r
+need to return to those hungry web clients in the shortest time possible.</p></div>\r
+</div>\r
+</div>\r
+<h2 id="_basic_caching">1. Basic Caching</h2>\r
+<div class="sectionbody">\r
+<div class="para"><p>This is an introduction to the three types of caching techniques that Rails\r
+provides by default without the use of any third party plugins.</p></div>\r
+<div class="para"><p>To get started make sure config.action_controller.perform_caching is set\r
+to true for your environment. This flag is normally set in the\r
+corresponding config/environments/*.rb and caching is disabled by default\r
+there for development and test, and enabled for production.</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt>config<span style="color: #990000">.</span>action_controller<span style="color: #990000">.</span>perform_caching <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>\r
+</tt></pre></div></div>\r
+<h3 id="_page_caching">1.1. Page Caching</h3>\r
+<div class="para"><p>Page caching is a Rails mechanism which allows the request for a generated\r
+page to be fulfilled by the webserver, without ever having to go through the\r
+Rails stack at all. Obviously, this is super-fast. Unfortunately, it can't be\r
+applied to every situation (such as pages that need authentication) and since\r
+the webserver is literally just serving a file from the filesystem, cache\r
+expiration is an issue that needs to be dealt with.</p></div>\r
+<div class="para"><p>So, how do you enable this super-fast cache behavior? Simple, let's say you\r
+have a controller called ProductsController and a <em>list</em> action that lists all\r
+the products</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductsController <span style="color: #990000"><</span> ActionController\r
+\r
+ caches_page <span style="color: #990000">:</span>index\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> index<span style="color: #990000">;</span> <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>The first time anyone requests products/index, Rails will generate a file\r
+called index.html and the webserver will then look for that file before it\r
+passes the next request for products/index to your Rails application.</p></div>\r
+<div class="para"><p>By default, the page cache directory is set to Rails.public_path (which is\r
+usually set to RAILS_ROOT + "/public") and this can be configured by\r
+changing the configuration setting ActionController::Base.page_cache_directory. Changing the\r
+default from /public helps avoid naming conflicts, since you may want to\r
+put other static html in /public, but changing this will require web\r
+server reconfiguration to let the web server know where to serve the\r
+cached files from.</p></div>\r
+<div class="para"><p>The Page Caching mechanism will automatically add a .html exxtension to\r
+requests for pages that do not have an extension to make it easy for the\r
+webserver to find those pages and this can be configured by changing the\r
+configuration setting ActionController::Base.page_cache_extension.</p></div>\r
+<div class="para"><p>In order to expire this page when a new product is added we could extend our\r
+example controler like this:</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductsController <span style="color: #990000"><</span> ActionController\r
+\r
+ caches_page <span style="color: #990000">:</span>list\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> list<span style="color: #990000">;</span> <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create\r
+ expire_page <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #990000">:</span>list\r
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>If you want a more complicated expiration scheme, you can use cache sweepers\r
+to expire cached objects when things change. This is covered in the section on Sweepers.</p></div>\r
+<h3 id="_action_caching">1.2. Action Caching</h3>\r
+<div class="para"><p>One of the issues with Page Caching is that you cannot use it for pages that\r
+require to restrict access somehow. This is where Action Caching comes in.\r
+Action Caching works like Page Caching except for the fact that the incoming\r
+web request does go from the webserver to the Rails stack and Action Pack so\r
+that before filters can be run on it before the cache is served, so that\r
+authentication and other restrictions can be used while still serving the\r
+result of the output from a cached copy.</p></div>\r
+<div class="para"><p>Clearing the cache works in the exact same way as with Page Caching.</p></div>\r
+<div class="para"><p>Let's say you only wanted authenticated users to edit or create a Product\r
+object, but still cache those pages:</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductsController <span style="color: #990000"><</span> ActionController\r
+\r
+ before_filter <span style="color: #990000">:</span>authenticate<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=></span> <span style="color: #990000">[</span> <span style="color: #990000">:</span>edit<span style="color: #990000">,</span> <span style="color: #990000">:</span>create <span style="color: #990000">]</span>\r
+ caches_page <span style="color: #990000">:</span>list\r
+ caches_action <span style="color: #990000">:</span>edit\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> list<span style="color: #990000">;</span> <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create\r
+ expire_page <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #990000">:</span>list\r
+ expire_action <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #990000">:</span>edit\r
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> edit<span style="color: #990000">;</span> <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>And you can also use :if (or :unless) to pass a Proc that specifies when the\r
+action should be cached. Also, you can use :layout ⇒ false to cache without\r
+layout so that dynamic information in the layout such as logged in user info\r
+or the number of items in the cart can be left uncached. This feature is\r
+available as of Rails 2.2.</p></div>\r
+<div class="para"><p>[More: more examples? Walk-through of Action Caching from request to response?\r
+ Description of Rake tasks to clear cached files? Show example of\r
+ subdomain caching? Talk about :cache_path, :if and assing blocks/Procs\r
+ to expire_action?]</p></div>\r
+<h3 id="_fragment_caching">1.3. Fragment Caching</h3>\r
+<div class="para"><p>Life would be perfect if we could get away with caching the entire contents of\r
+a page or action and serving it out to the world. Unfortunately, dynamic web\r
+applications usually build pages with a variety of components not all of which\r
+have the same caching characteristics. In order to address such a dynamically\r
+created page where different parts of the page need to be cached and expired\r
+differently Rails provides a mechanism called Fragment Caching.</p></div>\r
+<div class="para"><p>Fragment Caching allows a fragment of view logic to be wrapped in a cache\r
+block and served out of the cache store when the next request comes in.</p></div>\r
+<div class="para"><p>As an example, if you wanted to show all the orders placed on your website\r
+in real time and didn't want to cache that part of the page, but did want\r
+to cache the part of the page which lists all products available, you\r
+could use this piece of code:</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt><span style="color: #FF0000"><% Order.find_recent.each do |o| %></span>\r
+ <span style="color: #FF0000"><%= o.buyer.name %></span> bought <span style="color: #FF0000"><% o.product.name %></span>\r
+<span style="color: #FF0000"><% end %></span>\r
+\r
+<span style="color: #FF0000"><% cache do %></span>\r
+ All available products<span style="color: #990000">:</span>\r
+ <span style="color: #FF0000"><% Product.find(:all).each do |p| %></span>\r
+ <span style="color: #FF0000"><%= link_to p.name, product_url(p) %></span>\r
+ <span style="color: #FF0000"><% end %></span>\r
+<span style="color: #FF0000"><% end %></span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>The cache block in our example will bind to the action that called it and is\r
+written out to the same place as the Action Cache, which means that if you\r
+want to cache multiple fragments per action, you should provide an action_suffix to the cache call:</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt><span style="color: #FF0000"><% cache(:action =></span> <span style="color: #FF0000">'recent'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action_suffix <span style="color: #990000">=></span> <span style="color: #FF0000">'all_products'</span><span style="color: #990000">)</span> <span style="font-weight: bold"><span style="color: #0000FF">do</span></span> <span style="color: #990000">%></span>\r
+ All available products<span style="color: #990000">:</span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>and you can expire it using the expire_fragment method, like so:</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt>expire_fragment<span style="color: #990000">(:</span>controller <span style="color: #990000">=></span> <span style="color: #FF0000">'producst'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #FF0000">'recent'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action_suffix <span style="color: #990000">=></span> 'all_products<span style="color: #990000">)</span>\r
+</tt></pre></div></div>\r
+<h3 id="_sweepers">1.4. Sweepers</h3>\r
+<div class="para"><p>Cache sweeping is a mechanism which allows you to get around having a ton of\r
+expire_{page,action,fragment} calls in your code by moving all the work\r
+required to expire cached content into a ActionController::Caching::Sweeper\r
+class that is an Observer and looks for changes to an object via callbacks,\r
+and when a change occurs it expires the caches associated with that object n\r
+an around or after filter.</p></div>\r
+<div class="para"><p>Continuing with our Product controller example, we could rewrite it with a\r
+sweeper such as the following:</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> StoreSweeper <span style="color: #990000"><</span> ActionController<span style="color: #990000">::</span>Caching<span style="color: #990000">::</span>Sweeper\r
+ observe Product <span style="font-style: italic"><span style="color: #9A1900"># This sweeper is going to keep an eye on the Post model</span></span>\r
+\r
+ <span style="font-style: italic"><span style="color: #9A1900"># If our sweeper detects that a Post was created call this</span></span>\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> after_create<span style="color: #990000">(</span>product<span style="color: #990000">)</span>\r
+ expire_cache_for<span style="color: #990000">(</span>product<span style="color: #990000">)</span>\r
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ <span style="font-style: italic"><span style="color: #9A1900"># If our sweeper detects that a Post was updated call this</span></span>\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> after_update<span style="color: #990000">(</span>product<span style="color: #990000">)</span>\r
+ expire_cache_for<span style="color: #990000">(</span>product<span style="color: #990000">)</span>\r
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ <span style="font-style: italic"><span style="color: #9A1900"># If our sweeper detects that a Post was deleted call this</span></span>\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> after_destroy<span style="color: #990000">(</span>product<span style="color: #990000">)</span>\r
+ expire_cache_for<span style="color: #990000">(</span>product<span style="color: #990000">)</span>\r
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ private\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> expire_cache_for<span style="color: #990000">(</span>record<span style="color: #990000">)</span>\r
+ <span style="font-style: italic"><span style="color: #9A1900"># Expire the list page now that we added a new product</span></span>\r
+ expire_page<span style="color: #990000">(:</span>controller <span style="color: #990000">=></span> <span style="color: #FF0000">'#{record}'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #FF0000">'list'</span><span style="color: #990000">)</span>\r
+\r
+ <span style="font-style: italic"><span style="color: #9A1900"># Expire a fragment</span></span>\r
+ expire_fragment<span style="color: #990000">(:</span>controller <span style="color: #990000">=></span> <span style="color: #FF0000">'#{record}'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #FF0000">'recent'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action_suffix <span style="color: #990000">=></span> <span style="color: #FF0000">'all_products'</span><span style="color: #990000">)</span>\r
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>Then we add it to our controller to tell it to call the sweeper when certain\r
+actions are called. So, if we wanted to expire the cached content for the\r
+list and edit actions when the create action was called, we could do the\r
+following:</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductsController <span style="color: #990000"><</span> ActionController\r
+\r
+ before_filter <span style="color: #990000">:</span>authenticate<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=></span> <span style="color: #990000">[</span> <span style="color: #990000">:</span>edit<span style="color: #990000">,</span> <span style="color: #990000">:</span>create <span style="color: #990000">]</span>\r
+ caches_page <span style="color: #990000">:</span>list\r
+ caches_action <span style="color: #990000">:</span>edit\r
+ cache_sweeper <span style="color: #990000">:</span>store_sweeper<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=></span> <span style="color: #990000">[</span> <span style="color: #990000">:</span>create <span style="color: #990000">]</span>\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> list<span style="color: #990000">;</span> <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create\r
+ expire_page <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #990000">:</span>list\r
+ expire_action <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #990000">:</span>edit\r
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> edit<span style="color: #990000">;</span> <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+</tt></pre></div></div>\r
+<h3 id="_sql_caching">1.5. SQL Caching</h3>\r
+<div class="para"><p>Query caching is a Rails feature that caches the result set returned by each\r
+query so that if Rails encounters the same query again for that request, it\r
+will used the cached result set as opposed to running the query against the\r
+database again.</p></div>\r
+<div class="para"><p>For example:</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductsController <span style="color: #990000"><</span> ActionController\r
+\r
+ before_filter <span style="color: #990000">:</span>authenticate<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=></span> <span style="color: #990000">[</span> <span style="color: #990000">:</span>edit<span style="color: #990000">,</span> <span style="color: #990000">:</span>create <span style="color: #990000">]</span>\r
+ caches_page <span style="color: #990000">:</span>list\r
+ caches_action <span style="color: #990000">:</span>edit\r
+ cache_sweeper <span style="color: #990000">:</span>store_sweeper<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=></span> <span style="color: #990000">[</span> <span style="color: #990000">:</span>create <span style="color: #990000">]</span>\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> list\r
+ <span style="font-style: italic"><span style="color: #9A1900"># Run a find query</span></span>\r
+ Product<span style="color: #990000">.</span>find<span style="color: #990000">(:</span>all<span style="color: #990000">)</span>\r
+\r
+ <span style="color: #990000">...</span>\r
+\r
+ <span style="font-style: italic"><span style="color: #9A1900"># Run the same query again</span></span>\r
+ Product<span style="color: #990000">.</span>find<span style="color: #990000">(:</span>all<span style="color: #990000">)</span>\r
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create\r
+ expire_page <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #990000">:</span>list\r
+ expire_action <span style="color: #990000">:</span>action <span style="color: #990000">=></span> <span style="color: #990000">:</span>edit\r
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> edit<span style="color: #990000">;</span> <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+\r
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>In the <em>list</em> action above, the result set returned by the first\r
+Product.find(:all) will be cached and will be used to avoid querying the\r
+database again the second time that finder is called.</p></div>\r
+<div class="para"><p>Query caches are created at the start of an action and destroyed at the end of\r
+that action and thus persist only for the duration of the action.</p></div>\r
+<h3 id="_cache_stores">1.6. Cache stores</h3>\r
+<div class="para"><p>Rails provides different stores for the cached data for action and fragment\r
+caches. Page caches are always stored on disk.</p></div>\r
+<div class="para"><p>The cache stores provided include:</p></div>\r
+<div class="para"><p>1) Memory store: Cached data is stored in the memory allocated to the Rails\r
+ process, which is fine for WEBrick and for FCGI (if you\r
+ don't care that each FCGI process holds its own fragment\r
+ store). It's not suitable for CGI as the process is thrown\r
+ away at the end of each request. It can potentially also\r
+ take up a lot of memory since each process keeps all the\r
+ caches in memory.</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt>ActionController<span style="color: #990000">::</span>Base<span style="color: #990000">.</span>cache_store <span style="color: #990000">=</span> <span style="color: #990000">:</span>memory_store\r
+</tt></pre></div></div>\r
+<div class="para"><p>2) File store: Cached data is stored on the disk, this is the default store\r
+ and the default path for this store is: /tmp/cache. Works\r
+ well for all types of environments and allows all processes\r
+ running from the same application directory to access the\r
+ cached content.</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt>ActionController<span style="color: #990000">::</span>Base<span style="color: #990000">.</span>cache_store <span style="color: #990000">=</span> <span style="color: #990000">:</span>file_store<span style="color: #990000">,</span> <span style="color: #FF0000">"/path/to/cache/directory"</span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>3) DRb store: Cached data is stored in a separate shared DRb process that all\r
+ servers communicate with. This works for all environments and\r
+ only keeps one cache around for all processes, but requires\r
+ that you run and manage a separate DRb process.</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt>ActionController<span style="color: #990000">::</span>Base<span style="color: #990000">.</span>cache_store <span style="color: #990000">=</span> <span style="color: #990000">:</span>drb_store<span style="color: #990000">,</span> <span style="color: #FF0000">"druby://localhost:9192"</span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>4) MemCached store: Works like DRbStore, but uses Danga's MemCache instead.\r
+ Requires the ruby-memcache library:\r
+ gem install ruby-memcache.</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt>ActionController<span style="color: #990000">::</span>Base<span style="color: #990000">.</span>cache_store <span style="color: #990000">=</span> <span style="color: #990000">:</span>mem_cache_store<span style="color: #990000">,</span> <span style="color: #FF0000">"localhost"</span>\r
+</tt></pre></div></div>\r
+<div class="para"><p>5) Custom store: You can define your own cache store (new in Rails 2.1)</p></div>\r
+<div class="listingblock">\r
+<div class="content"><!-- Generator: GNU source-highlight 2.9\r
+by Lorenzo Bettini\r
+http://www.lorenzobettini.it\r
+http://www.gnu.org/software/src-highlite -->\r
+<pre><tt>ActionController<span style="color: #990000">::</span>Base<span style="color: #990000">.</span>cache_store <span style="color: #990000">=</span> MyOwnStore<span style="color: #990000">.</span>new<span style="color: #990000">(</span><span style="color: #FF0000">"parameter"</span><span style="color: #990000">)</span>\r
+</tt></pre></div></div>\r
+</div>\r
+<h2 id="_advanced_caching">2. Advanced Caching</h2>\r
+<div class="sectionbody">\r
+<div class="para"><p>Along with the built-in mechanisms outlined above, a number of excellent\r
+plugins exist to help with finer grained control over caching. These include\r
+Chris Wanstrath's excellent cache_fu plugin (more info here:\r
+<a href="http://errtheblog.com/posts/57-kickin-ass-w-cachefu">http://errtheblog.com/posts/57-kickin-ass-w-cachefu</a>) and Evan Weaver's\r
+interlock plugin (more info here:\r
+<a href="http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/">http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/</a>). Both\r
+of these plugins play nice with memcached and are a must-see for anyone\r
+seriously considering optimizing their caching needs.</p></div>\r
+</div>\r
+
+ </div>
+ </div>
+</body>
+</html>