Rails offer a multi-level view caching based on: page, action and fragment.

Page Caching

For Rails cache a page means to generate the HTML code on the first visit, then allow front-end web server to send it statically.
This is the fastest way to serve pages, because Rails puts the cached page in the public folder, the web server intercept the request and doesn’t forward it to the application server, avoiding an useless Rails request cycle.
class HomeController

Unfortunately, this approach doesn’t fit for all the needs. Since page caching is URL based, it’s the ideal solution for stateless pages, with no personalized data (for instance: account pages).

Action Caching

Action caching is similar to page caching: when an user visit for the first time a certain route, the page will be generated, but cached by the Rails internal mechanism (disk, memory, MemCache). The other big difference is that the request will be always forwarded to the application server, and it will pass through ActionPack. In other words it means all the filters will be executed.
class PeopleController

This approach is ideal for protected contents, in the above example, the page will be fetched from the cache, only if the authenticate filter conditions are satisfied.

Fragment Caching

Fragment caching is the finest caching solution, as the name suggest it allows to cache page fragments.
Hello,

    'task', :collection => @tasks %>

We wrap all the contents that should be cached with the cache method. Since we pass an Array of identifiers to that method, ActionPack can recognize and serve the correct contents for each user.

Javascript

Fragment caching is the best solution for dynamic contents, but, at the same time, the hardest one to use, because complex cache expiring policies are involved with it. Often it’s the only solution to serve this kind of contents, because the other caching approaches are unusable.

DHH has recently posted an article about JavaScript and how it can make compatible page caching and relative times. It cache the whole page, then allow JavaScript to convert on fly from the UTC time to a literal representation like: “about 1 hour ago”.

I recently elaborated a similar technique. I use to apply the page cache strategy for the application home pages, since it deliveries only marketing stuff or introductory contents. But, what if a loggedin user visit the home page? Since it’s a cached page (aka stateless), it doesn’t recognize the user status, it’s pure HTML, in the end. Should I abandon the comfortably page caching, only for this problem? The answer is easy: no.

How Javascript helped me? First of all: I included the login box in the home page, just declaring it as hidden.

Second: when the user logs inside the application I send a cookie with the session status
class SessionController

The last step is to read the cookie content and show the login box if the user is loggedin.

// cookies.js var Document = { cookies: function(document){ return $A(document.cookie.split("; ")).inject($H({}), function(memo, pair){ pair = pair.split('='); memo.set(pair[0], pair[1]); return memo; }); } }; Object.extend(document, { cookies: Document.cookies.methodize() });

// application.js function handle_login_box() { if(document.cookies().get('loggedin') == "true"){ $('login_box').show(); } }

document.observe(“dom:loaded”, handle_login_box);

Hope this technique can help you, of course you can improve it with more complex user cases.