Thursday, August 25, 2016

Cache Strategies for Rails: Low level caching




Sometimes we take a look at our log entries and we can see that some queries are taking a lot of time, maybe because the query is too heavy, or maybe because we are calling several queries in order to paint all the necessary information.


Low-level caching entails using the Rails.cache object directly to cache any information. For instance, I am envisioning the thypical scenario where we need to show a dropdown with all cities of a country. Maybe this query it is not heavy, but several queries at the same time like this, may affect to the performance. So in this case could be interesting save this query in the cache:

The  application has a Country model with an instance method returning all cities by country. Obviously we hace another model called City. The data returned by this method would be perfect for low-level caching. It will read a value from the cache if it available; otherwise it will execute a block passed to it and return the result:


# country.rb

def all_cities_by_country
  Rails.cache.fetch("cities_by_country_#{self.id}") do
    City.all.where("cities.country_id = ?",self.id)
  end
end

Now you could be thinking what happen if the admin creates a new city in the database? No problem, we have two possibilities, we could add to the key the column updated_at, so in this way each time admin updates the table the cache will be updated the next time user calls this method.
The other option could be create a callback in the model, so any time the table is updated we can call a private method that will update the cache.

No comments:

Post a Comment