Rails.cache - working but not working

A4J picture A4J · Sep 20, 2012 · Viewed 7.1k times · Source

I am using Rails.cache (I have tried both default store and memcached with the dalli gem - but I get the same behaviour) it seems to be working, but isn't (logs show that the query is not made, but actual results show otherwise)... I have a search page that caches the top ten queries for 1 day:

search.rb

  def self.top_ten
    Rails.cache.fetch("top_ten_searches_cache", :expires_in => 1.day) do
      Search.order("count DESC").limit(10)
    end    
  end 

However, when I go to the search page, and enter a new search term, repeatedly, it begins to show in the top ten results! (Whereas I am not expecting the top ten results to change until 1 day passes.) When the cache store is default, no query shows in the log (so you think cache is working) and when using dalli/memcached I get exactly the same behaviour, but with this in the log:

Cache read: top_ten_searches_cache ({:expires_in=>1 day})
Cache fetch_hit: top_ten_searches_cache ({:expires_in=>1 day})

What does Cache fetch_hit mean exactly? Could it mean that no cache was found and is having to do the query?

Not really sure what's going on - it's odd that I get the same behaviour with either the default store or memcached with Dalli.

Answer

Mike Campbell picture Mike Campbell · Sep 20, 2012

You're caching the scope, not the actual results of the query. Rails uses lazy loading, so to force the query to execute you need to put .to_a (or .all in Rails 3), for example:

def self.top_ten
  Rails.cache.fetch("top_ten_searches_cache", :expires_in => 1.day) do
    Search.order("count DESC").limit(10).to_a
  end    
end 

See here.