aboutsummaryrefslogtreecommitdiffstats
path: root/railties/doc/guides/html/caching_with_rails.html
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2008-10-21 18:33:40 +0100
committerPratik Naik <pratiknaik@gmail.com>2008-10-21 18:33:40 +0100
commita03e2b356c66ddc8809fa2b23a2a7d652f173b8b (patch)
treeab8552913475bf94a78e4cbfbae804b2ecd9eca2 /railties/doc/guides/html/caching_with_rails.html
parent18542c9e00209679bdaacf64075819fb887ec856 (diff)
downloadrails-a03e2b356c66ddc8809fa2b23a2a7d652f173b8b.tar.gz
rails-a03e2b356c66ddc8809fa2b23a2a7d652f173b8b.tar.bz2
rails-a03e2b356c66ddc8809fa2b23a2a7d652f173b8b.zip
Merge with docrails. Also add a rake task to generate guides in your rails application :
rake doc:guides The rake task will generate guides inside doc/guides directory of your application. Open index.html to browse.
Diffstat (limited to 'railties/doc/guides/html/caching_with_rails.html')
-rw-r--r--railties/doc/guides/html/caching_with_rails.html577
1 files changed, 577 insertions, 0 deletions
diff --git a/railties/doc/guides/html/caching_with_rails.html b/railties/doc/guides/html/caching_with_rails.html
new file mode 100644
index 0000000000..df30c46c35
--- /dev/null
+++ b/railties/doc/guides/html/caching_with_rails.html
@@ -0,0 +1,577 @@
+<!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">
+<div class="sectionbody">
+<div class="para"><p>Everyone caches. This guide will teach you what you need to know about
+avoiding that expensive round-trip to your database and returning what you
+need to return to those hungry web clients in the shortest time possible.</p></div>
+</div>
+</div>
+<h2 id="_basic_caching">1. Basic Caching</h2>
+<div class="sectionbody">
+<div class="para"><p>This is an introduction to the three types of caching techniques that Rails
+provides by default without the use of any third party plugins.</p></div>
+<div class="para"><p>To get started make sure Base.perform_caching is set to true for your
+environment.</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt>Base<span style="color: #990000">.</span>perform_caching <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
+</tt></pre></div></div>
+<h3 id="_page_caching">1.1. Page Caching</h3>
+<div class="para"><p>Page caching is a Rails mechanism which allows the request for a generated
+page to be fulfilled by the webserver, without ever having to go through the
+Rails stack at all. Obviously, this is super fast. Unfortunately, it can't be
+applied to every situation (such as pages that need authentication) and since
+the webserver is literally just serving a file from the filesystem, cache
+expiration is an issue that needs to be dealt with.</p></div>
+<div class="para"><p>So, how do you enable this super-fast cache behavior? Simple, let's say you
+have a controller called ProductController and a <em>list</em> action that lists all
+the products</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductController <span style="color: #990000">&lt;</span> ActionController
+
+ cache_page <span style="color: #990000">:</span>list
+
+ <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>
+
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>The first time anyone requestsion products/list, Rails will generate a file
+called list.html and the webserver will then look for that file before it
+passes the next request for products/list to your Rails application.</p></div>
+<div class="para"><p>By default, the page cache directory is set to Rails.public_path (which is
+usually set to RAILS_ROOT + "/public") and this can be configured by changing
+the configuration setting Base.cache_public_directory</p></div>
+<div class="para"><p>The page caching mechanism will automatically add a .html exxtension to
+requests for pages that do not have an extension to make it easy for the
+webserver to find those pages and this can be configured by changing the
+configuration setting Base.page_cache_extension</p></div>
+<div class="para"><p>In order to expire this page when a new product is added we could extend our
+example controler like this:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductController <span style="color: #990000">&lt;</span> ActionController
+
+ cache_page <span style="color: #990000">:</span>list
+
+ <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>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
+ expire_page <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>list
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>If you want a more complicated expiration scheme, you can use cache sweepers
+to expire cached objects when things change. This is covered in the section on Sweepers.</p></div>
+<h3 id="_action_caching">1.2. Action Caching</h3>
+<div class="para"><p>One of the issues with page caching is that you cannot use it for pages that
+require to restrict access somehow. This is where Action Caching comes in.
+Action Caching works like Page Caching except for the fact that the incoming
+web request does go from the webserver to the Rails stack and Action Pack so
+that before_filters can be run on it before the cache is served, so that
+authentication and other restrictions can be used while still serving the
+result of the output from a cached copy.</p></div>
+<div class="para"><p>Clearing the cache works in the exact same way as with Page Caching.</p></div>
+<div class="para"><p>Let's say you only wanted authenticated users to edit or create a Product
+object, but still cache those pages:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductController <span style="color: #990000">&lt;</span> ActionController
+
+ before_filter <span style="color: #990000">:</span>authenticate<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=&gt;</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>
+ cache_page <span style="color: #990000">:</span>list
+ caches_action <span style="color: #990000">:</span>edit
+
+ <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>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
+ expire_page <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>list
+ expire_action <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>edit
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <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>
+
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>And you can also use :if (or :unless) to pass a Proc that specifies when the
+action should be cached. Also, you can use :layout &#8658; false to cache without
+layout so that dynamic information in the layout such as logged in user info
+or the number of items in the cart can be left uncached. This feature is
+available as of Rails 2.2.</p></div>
+<div class="para"><p>[More: more examples? Walk-through of action caching from request to response?
+ Description of Rake tasks to clear cached files? Show example of
+ subdomain caching? Talk about :cache_path, :if and assing blocks/Procs
+ to expire_action?]</p></div>
+<h3 id="_fragment_caching">1.3. Fragment Caching</h3>
+<div class="para"><p>Life would be perfect if we could get away with caching the entire contents of
+a page or action and serving it out to the world. Unfortunately, dynamic web
+applications usually build pages with a variety of components not all of which
+have the same caching characteristics. In order to address such a dynamically
+created page where different parts of the page need to be cached and expired
+differently Rails provides a mechanism called Fragment caching.</p></div>
+<div class="para"><p>Fragment caching allows a fragment of view logic to be wrapped in a cache
+block and served out of the cache store when the next request comes in.</p></div>
+<div class="para"><p>As an example, if you wanted to show all the orders placed on your website in
+real time and didn't want to cache that part of the page, but did want to
+cache the part of the page which lists all products available, you could use
+this piece of code:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="color: #FF0000">&lt;% Order.find_recent.each do |o| %&gt;</span>
+ <span style="color: #FF0000">&lt;%= o.buyer.name %&gt;</span> bought <span style="color: #FF0000">&lt;% o.product.name %&gt;</span>
+<span style="color: #FF0000">&lt;% end %&gt;</span>
+
+<span style="color: #FF0000">&lt;% cache do %&gt;</span>
+ All available products<span style="color: #990000">:</span>
+ <span style="color: #FF0000">&lt;% Product.find(:all).each do |p| %&gt;</span>
+ <span style="color: #FF0000">&lt;%= link_to p.name, product_url(p) %&gt;</span>
+ <span style="color: #FF0000">&lt;% end %&gt;</span>
+<span style="color: #FF0000">&lt;% end %&gt;</span>
+</tt></pre></div></div>
+<div class="para"><p>The cache block in our example will bind to the action that called it and is
+written out to the same place as the Action Cache, which means that if you
+want to cache multiple fragments per action, you should provide an action_path to the cache call:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="color: #FF0000">&lt;% cache(:action =&gt;</span> <span style="color: #FF0000">'recent'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action_suffix <span style="color: #990000">=&gt;</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">%&gt;</span>
+ All available products<span style="color: #990000">:</span>
+</tt></pre></div></div>
+<div class="para"><p>and you can expire it using the expire_fragment method, like so:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt>expire_fragment<span style="color: #990000">(:</span>controller <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'producst'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'recent'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action_suffix <span style="color: #990000">=&gt;</span> 'all_products<span style="color: #990000">)</span>
+</tt></pre></div></div>
+<h3 id="_sweepers">1.4. Sweepers</h3>
+<div class="para"><p>Cache sweeping is a mechanism which allows you to get around having a ton of
+expire_{page,action,fragment} calls in your code by moving all the work
+required to expire cached content into a ActionController::Caching::Sweeper
+class that is an Observer and looks for changes to an object via callbacks,
+and when a change occurs it expires the caches associated with that object n
+an around or after filter.</p></div>
+<div class="para"><p>Continuing with our Product controller example, we could rewrite it with a
+sweeper such as the following:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> StoreSweeper <span style="color: #990000">&lt;</span> ActionController<span style="color: #990000">::</span>Caching<span style="color: #990000">::</span>Sweeper
+ 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>
+
+ <span style="font-style: italic"><span style="color: #9A1900"># If our sweeper detects that a Post was created call this</span></span>
+ <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>
+ expire_cache_for<span style="color: #990000">(</span>product<span style="color: #990000">)</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-style: italic"><span style="color: #9A1900"># If our sweeper detects that a Post was updated call this</span></span>
+ <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>
+ expire_cache_for<span style="color: #990000">(</span>product<span style="color: #990000">)</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-style: italic"><span style="color: #9A1900"># If our sweeper detects that a Post was deleted call this</span></span>
+ <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>
+ expire_cache_for<span style="color: #990000">(</span>product<span style="color: #990000">)</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ private
+ <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>
+ <span style="font-style: italic"><span style="color: #9A1900"># Expire the list page now that we added a new product</span></span>
+ expire_page<span style="color: #990000">(:</span>controller <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'#{record}'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'list'</span><span style="color: #990000">)</span>
+
+ <span style="font-style: italic"><span style="color: #9A1900"># Expire a fragment</span></span>
+ expire_fragment<span style="color: #990000">(:</span>controller <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'#{record}'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'recent'</span><span style="color: #990000">,</span> <span style="color: #990000">:</span>action_suffix <span style="color: #990000">=&gt;</span> <span style="color: #FF0000">'all_products'</span><span style="color: #990000">)</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>Then we add it to our controller to tell it to call the sweeper when certain
+actions are called. So, if we wanted to expire the cached content for the
+list and edit actions when the create action was called, we could do the
+following:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductController <span style="color: #990000">&lt;</span> ActionController
+
+ before_filter <span style="color: #990000">:</span>authenticate<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=&gt;</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>
+ cache_page <span style="color: #990000">:</span>list
+ caches_action <span style="color: #990000">:</span>edit
+ cache_sweeper <span style="color: #990000">:</span>store_sweeper<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=&gt;</span> <span style="color: #990000">[</span> <span style="color: #990000">:</span>create <span style="color: #990000">]</span>
+
+ <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>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
+ expire_page <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>list
+ expire_action <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>edit
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <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>
+
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<h3 id="_sql_caching">1.5. SQL Caching</h3>
+<div class="para"><p>Query caching is a Rails feature that caches the result set returned by each
+query so that if Rails encounters the same query again for that request, it
+will used the cached result set as opposed to running the query against the
+database again.</p></div>
+<div class="para"><p>For example:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> ProductController <span style="color: #990000">&lt;</span> ActionController
+
+ before_filter <span style="color: #990000">:</span>authenticate<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=&gt;</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>
+ cache_page <span style="color: #990000">:</span>list
+ caches_action <span style="color: #990000">:</span>edit
+ cache_sweeper <span style="color: #990000">:</span>store_sweeper<span style="color: #990000">,</span> <span style="color: #990000">:</span>only <span style="color: #990000">=&gt;</span> <span style="color: #990000">[</span> <span style="color: #990000">:</span>create <span style="color: #990000">]</span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> list
+ <span style="font-style: italic"><span style="color: #9A1900"># Run a find query</span></span>
+ Product<span style="color: #990000">.</span>find<span style="color: #990000">(:</span>all<span style="color: #990000">)</span>
+
+ <span style="color: #990000">...</span>
+
+ <span style="font-style: italic"><span style="color: #9A1900"># Run the same query again</span></span>
+ Product<span style="color: #990000">.</span>find<span style="color: #990000">(:</span>all<span style="color: #990000">)</span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> create
+ expire_page <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>list
+ expire_action <span style="color: #990000">:</span>action <span style="color: #990000">=&gt;</span> <span style="color: #990000">:</span>edit
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+
+ <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>
+
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
+<div class="para"><p>In the <em>list</em> action above, the result set returned by the first
+Product.find(:all) will be cached and will be used to avoid querying the
+database again the second time that finder is called.</p></div>
+<div class="para"><p>Query caches are created at the start of an action and destroyed at the end of
+that action and thus persist only for the duration of the action.</p></div>
+<h3 id="_cache_stores">1.6. Cache stores</h3>
+<div class="para"><p>Rails provides different stores for the cached data for action and fragment
+caches. Page caches are always stored on disk.</p></div>
+<div class="para"><p>The cache stores provided include:</p></div>
+<div class="para"><p>1) Memory store: Cached data is stored in the memory allocated to the Rails
+ process, which is fine for WEBrick and for FCGI (if you
+ don't care that each FCGI process holds its own fragment
+ store). It's not suitable for CGI as the process is thrown
+ away at the end of each request. It can potentially also
+ take up a lot of memory since each process keeps all the
+ caches in memory.</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<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
+</tt></pre></div></div>
+<div class="para"><p>2) File store: Cached data is stored on the disk, this is the default store
+ and the default path for this store is: /tmp/cache. Works
+ well for all types of environments and allows all processes
+ running from the same application directory to access the
+ cached content.</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<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>
+</tt></pre></div></div>
+<div class="para"><p>3) DRb store: Cached data is stored in a separate shared DRb process that all
+ servers communicate with. This works for all environments and
+ only keeps one cache around for all processes, but requires
+ that you run and manage a separate DRb process.</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<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>
+</tt></pre></div></div>
+<div class="para"><p>4) MemCached store: Works like DRbStore, but uses Danga's MemCache instead.
+ Requires the ruby-memcache library:
+ gem install ruby-memcache.</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<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>
+</tt></pre></div></div>
+<div class="para"><p>5) Custom store: You can define your own cache store (new in Rails 2.1)</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<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>
+</tt></pre></div></div>
+</div>
+<h2 id="_advanced_caching">2. Advanced Caching</h2>
+<div class="sectionbody">
+<div class="para"><p>Along with the built-in mechanisms outlined above, a number of excellent
+plugins exist to help with finer grained control over caching. These include
+Chris Wanstrath's excellent cache_fu plugin (more info here:
+<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
+interlock plugin (more info here:
+<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
+of these plugins play nice with memcached and are a must-see for anyone
+seriously considering optimizing their caching needs.</p></div>
+</div>
+
+ </div>
+ </div>
+</body>
+</html>