views:

288

answers:

2

When I have 2 views that fragment cache the same query BUT display them differently, there is only one fragment and they both display it the same way. Is there any way around this? For example...

#views/posts/list
    - cache(@posts) do
         - for p in @posts
              = p.title

#views/posts/list_with_images
    - cache(@posts) do
         - for p in @posts
              = p.title
              = p.content
              = image_tag(p.image_url)

#controllers/posts_controller
     def list
        ...
        @posts = Post.all
     end

     def list_with_images
        ...
        @posts = Post.all
     end
A: 

I figured it out.

First of all, the whole point of this strategy is to make use of the intelligent cache keys in rails, which auto-generate unique keys based on the model name, ID, and updated_at attributes.

What if you have content that refers to two models? There is a convention for this built-in, you simply use an array:

- cache([@posts, @user]) do

And this just appends a user key to the posts key, so that if either is updated the cache automatically expires. You can use this same convention to add additional information to the key in the form of a plain string. This is useful for distinguishing between fragments that draw on the same query but require different views, and is the answer to the question above.

- cache([@posts, "lists"]) do

and then on the other page use

- cache([@posts, "list_with_images"]) do

and this will create two separate fragments that won't be confused with each other.

Michael Waxman
+3  A: 

You have to use a unique cache key. If you simple pass in an object it calls the cache_key method on it to determine the key. If you pass in an array of objects, cache will generate a key by joining the cache keys of all the elements of the array. You can use this to fix your problem through:

#views/posts/list
    - cache([:list, @posts]) do
         - for p in @posts
              = p.title

#views/posts/list_with_images
    - cache([:list_with_images, @posts]) do
         - for p in @posts
              = p.title
              = p.content
              = image_tag(p.image_url)
gregor