diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2008-10-21 18:33:40 +0100 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2008-10-21 18:33:40 +0100 |
commit | a03e2b356c66ddc8809fa2b23a2a7d652f173b8b (patch) | |
tree | ab8552913475bf94a78e4cbfbae804b2ecd9eca2 /railties/doc/guides/html/caching_with_rails.html | |
parent | 18542c9e00209679bdaacf64075819fb887ec856 (diff) | |
download | rails-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.html | 577 |
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"><</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"><</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">=></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"><</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">=></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">=></span> <span style="color: #990000">:</span>list
+ expire_action <span style="color: #990000">:</span>action <span style="color: #990000">=></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 ⇒ 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"><% Order.find_recent.each do |o| %></span>
+ <span style="color: #FF0000"><%= o.buyer.name %></span> bought <span style="color: #FF0000"><% o.product.name %></span>
+<span style="color: #FF0000"><% end %></span>
+
+<span style="color: #FF0000"><% cache do %></span>
+ All available products<span style="color: #990000">:</span>
+ <span style="color: #FF0000"><% Product.find(:all).each do |p| %></span>
+ <span style="color: #FF0000"><%= link_to p.name, product_url(p) %></span>
+ <span style="color: #FF0000"><% end %></span>
+<span style="color: #FF0000"><% end %></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"><% 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>
+ 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">=></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>
+</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"><</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">=></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>
+
+ <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">=></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>
+ <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"><</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">=></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">=></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">=></span> <span style="color: #990000">:</span>list
+ expire_action <span style="color: #990000">:</span>action <span style="color: #990000">=></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"><</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">=></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">=></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">=></span> <span style="color: #990000">:</span>list
+ expire_action <span style="color: #990000">:</span>action <span style="color: #990000">=></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> |