RE: time based caching on rails pages

Hi Sam!

Some time ago I was looking for the same functionality but also couldn’t
find it.

Just to make sure you want the same thing: I needed this for a ‘status’
page that was periodically updated using ajax. The queries needed to
build this page are quite expensive, so I wanted to make sure that if
e.g. 20 client browsers are looking at this page, it isn’t updated for
each client request because this would be quite unfriendly for the
database. The status page is the same for all clients, and knowing these
people I also wanted to avoid them pressing refresh like crazy until
they see ‘their’ thing happening.

I made a function that is called with a key and a timeout value in
seconds. If the function returns ‘true’ it timed out and you need to
rebuild the page. The timeout value is written in a yml file (this was
for a system with legacy database that I couldn’t make any changes to or
add new tables). I can’t remember the exact details, but hopefully the
code below will help you on your way.

in my controller:

#ajax response handler
def update_statuses
if cache_timedout(‘list_statuses’, 60)
@statuses = [expensive query]
render :partial => “statuses”

#function to handle cache timeout by writing timeout to yaml file
def cache_timedout(key, timeout)
filename = “#{RAILS_ROOT}/tmp/cache/#{key}.yml”

if read_fragment(:controller=>'status', :action => key)
  if File.exist?(filename)
    cachetime = YAML::load(
    if cachetime >
      return false

expire_fragment :action => key, 'w') do |file|
  YAML::dump(( + timeout.seconds), file)


in my ‘statuses’ view (a partial actually for the ajax request):
<% cache(:action => “list_statuses”) do %>
[display/format content of @statuses]
<% end %>

I remember I first used something else (more logical) instead of
read_fragment to check for existense of the fragment, which didn’t work.
Also, theoretically it would be possible for the fragment to expire by
another process after the cache_timedout check in the controller and
before the view is called, resulting in an empty @statuses array in the
view. Knowing the users though (this is an internal app), they would
just ignore the error and refresh the page. Finding a decent soultion to
such a minor issue would have been a waste of time at that time.

Hope this is enough. Some names have been changed to protect the
probably not so innocent :wink:


-----Original Message-----
From: [email protected]

[mailto:[email protected]] On Behalf Of Sam D.
Sent: donderdag 3 augustus 2006 12:56
To: [email protected]
Subject: [Rails] time based caching on rails pages.


Quick question on caching based on time based expiration.  Is

something that rails supports? Is there a way to instruct rails
refetch the new page after a time period or do we actually have
to spawn
a background process and have it expire the pages.



Posted via
Rails mailing list
[email protected]