# Need suggestions for caching strategy

**URL:** <https://www.ruby-forum.com/t/need-suggestions-for-caching-strategy/148997>\
**Category:** Rails\
**Created:** [September 19, 2008, 5:39am UTC](https://www.ruby-forum.com/t/need-suggestions-for-caching-strategy/148997 "2008-09-19T05:39:17Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![rubynuby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ba9def/32.png) [@rubynuby](https://www.ruby-forum.com/u/rubynuby)\
**Post date:** [September 19, 2008, 5:39am UTC](https://www.ruby-forum.com/t/need-suggestions-for-caching-strategy/148997/1 "2008-09-19T05:39:17Z")

</div>

I’m developing a content sharing site. (Closest analogy is something  
like [docstoc.com](http://docstoc.com).) I find that page caching isn’t practical since  
many things will change depending on whether the user is logged in or  
not. Example: the banner on top will have the user’s name, a sign off  
link, the side bars will have his profile and recent activities, etc,  
which is unique for each user.

Even fragment caching is difficult. For example, in a listing of  
documents, each item has a star rating. If the user has voted on that  
item or the item belongs to him, I hide the vote link. So I can’t  
exactly cache the list of most recent documents.

If the user isn’t logged in, then I can do a lot more with caching. I  
guess I want to do conditional caching.

What are some general strategies for handling caching in a situation  
like this?

---

<div class="post-metadata">

**Author:** ![rubynuby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/ba9def/32.png) [@rubynuby](https://www.ruby-forum.com/u/rubynuby)\
**Post date:** [September 19, 2008, 3:46pm UTC](https://www.ruby-forum.com/t/need-suggestions-for-caching-strategy/148997/2 "2008-09-19T15:46:55Z")

</div>

> What are some general strategies for handling caching in a situation  
> like this?

Fragment caching sounds like the way to go.

For index views, I cache my “standard” data on a per row basis, but not  
the edit/destroy links, as those depend on the user viewing the data and  
their rights/permissions. The caching still helps with performance  
since the “standard” data includes columns assembled from other models  
in the database, and I don’t use eager loading.

Naming your fragments specifically makes the cache management easier in  
a complicated case (I use a modeltype.id.cachetype naming scheme like  
project.1.show, project.1.relateds, project.1.related.scenarios, etc).

I wouldn’t bother caching the banner.  
You could cache all but the voting link on the index view (just make  
that the first or last item on the row for simplicity).  
I wouldn’t cache your sidebar, as it would change frequently (unless it  
can be broken into chunks like profile, recent this, recent that).

My sidebar in a ‘show’ method shows all the models related to the  
current model grouped by model type (a project can have related  
scenarios, images, applications, modules, and areas). I cache the whole  
‘related’ sidebar, as well as the sidebar components – related models  
of type X. When a new scenario gets related to a project, for example,  
that expires the project’s ‘related scenarios’ fragment, and the overall  
‘related models’ fragment. Next time the project is viewed, the missing  
‘related models’ fragment means that it has to check each related model  
fragment. In this case only the related scenarios would have to be  
re-read and a new cache fragment generated – the other 4 fragments are  
still valid.

All that kind of work and logic is coded in a GenericModel class that  
sits between ActiveRecord::Base and my real models like Project,  
Scenario, etc, so it’s easy to have new models adopt the caching  
mechanism.
