views:

71

answers:

1

I need to cache (and expire) all the models in a table.

For example, if i have a model named Currency, i only have less than 10 possible currencies. Therefore, it would be nice to have:

class Currency < ActiveRecord::Base
  cache_all(:expire_in => 10.minutes)
end

so that

Currency.all
Currency.find_by_name("USD")

should not hit the DB.

What do you think it could be a good approach?

Also, if you believe it would be better to use a model that is not backed up by a DB, please comment on this. Please notice that i would like to have a AR-style association.

+4  A: 

Since the data set is so small, probably the best thing is to cache it in local memory. There are a couple ways to do this, one is to use Memoization like I show here. However that isn't the most efficient because it will store the all method and find_by_name method in separate caches even though they are the same object.

An alternative is to redefine the methods to cache the objects manually. Something like this.

class Currency < ActiveRecord::Base
  def self.all
    @all_cache ||= super.map(&:freeze) # freeze so you don't modify the cached objects
  end

  def self.find_by_name(name)
    all.detect { |c| c.name.to_s.downcase == name.to_s.downcase }
  end

  def self.flush_all_cache
    @all_cache = nil
  end
end

There may be a plugin to handle this for you, but I haven't looked into that at all.

ryanb
Thank you, Ryan :). I have also found the cached_model gem, but it seems a little old.. i will give it a try.
Vlad Zloteanu