diff options
author | Xavier Noria <fxn@hashref.com> | 2013-01-26 17:41:56 +0100 |
---|---|---|
committer | Xavier Noria <fxn@hashref.com> | 2013-01-26 17:41:56 +0100 |
commit | 0b5d3f32732f637fe29848a3597852dce9662c6b (patch) | |
tree | a0e75011bd90c1d7cde73a89b680c52ab0a589ec /guides/source/caching_with_rails.md | |
parent | 474e7dd82af030fb22ab5a586976d21b3497882a (diff) | |
parent | 4313461587254fd8e5b5a8ea7dfc9f0230c70ecb (diff) | |
download | rails-0b5d3f32732f637fe29848a3597852dce9662c6b.tar.gz rails-0b5d3f32732f637fe29848a3597852dce9662c6b.tar.bz2 rails-0b5d3f32732f637fe29848a3597852dce9662c6b.zip |
Merge remote-tracking branch 'docrails/master'
Conflicts:
actionpack/lib/action_view/helpers/form_options_helper.rb
guides/code/getting_started/app/controllers/comments_controller.rb
Diffstat (limited to 'guides/source/caching_with_rails.md')
-rw-r--r-- | guides/source/caching_with_rails.md | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md index 0228d463cf..e52264f296 100644 --- a/guides/source/caching_with_rails.md +++ b/guides/source/caching_with_rails.md @@ -85,6 +85,51 @@ This fragment is then available to all actions in the `ProductsController` using ```ruby expire_fragment('all_available_products') ``` +If you want to avoid expiring the fragment manually, whenever an action updates a product, you can define a helper method: + +```ruby +module ProductsHelper + def cache_key_for_products + count = Product.count + max_updated_at = Product.maximum(:updated_at).try(:utc).try(:to_s, :number) + "products/all-#{count}-#{max_updated_at}" + end +end +``` + +This method generates a cache key that depends on all products and can be used in the view: + +```ruby +<% cache(cache_key_for_products) do %> + All available products: +<% end %> +``` +You can also use an Active Record model as the cache key: + +```ruby +<% Product.all.each do |p| %> + <% cache(p) do %> + <%= link_to p.name, product_url(p) %> + <% end %> +<% end %> +``` + +Behind the scenes, a method called `cache_key` will be invoked on the model and it returns a string like `products/23-20130109142513`. The cache key includes the model name, the id and finally the updated_at timestamp. Thus it will automatically generate a new fragment when the product is updated because the key changes. + +You can also combine the two schemes which is called "Russian Doll Caching": + +```ruby +<% cache(cache_key_for_products) do %> + All available products: + <% Product.all.each do |p| %> + <% cache(p) do %> + <%= link_to p.name, product_url(p) %> + <% end %> + <% end %> +<% end %> +``` + +It's called "Russian Doll Caching" because it nests multiple fragments. The advantage is that if a single product is updated, all the other inner fragments can be reused when regenerating the outer fragment. ### SQL Caching @@ -93,7 +138,7 @@ Query caching is a Rails feature that caches the result set returned by each que For example: ```ruby -class ProductsController < ActionController +class ProductsController < ApplicationController def index # Run a find query |