0

I've got query in my Rails application that doesn't take long to run (~180ms), but does return a lot of results. The result is used in an API, and the transformation of the result to JSON is expensive (~3s). To speed things up, I'm caching it like this:

key = 'new_prices'
query = Prices.new_this_month.where('...')
json = cache(key, expires_in: 60.minutes) do
  render_to_string json: query, each_serializer: PriceSerializer
end
render json: json

In the background, new prices can be added to the database. How can I generate the cache key in such a way that if the result of query changes, the cache is invalidated?

I'm using Rails 3.2, with memcached via the dalli gem.

Sam Starling
  • 5,298
  • 3
  • 35
  • 52

1 Answers1

0

As you've got a new_this_month scope, I assume Prices have a created_at timestamp. In that case you could simply use the latest created_at in your cache key:

cache_key = "new_prices-#{Prices.order('created_at DESC').take.created_at}"

If you've got a good database index in place, this should be a very fast query.

fivedigit
  • 18,464
  • 6
  • 54
  • 58
  • It doesn't actually have a `created_at` date, but one can be deduced. I also think I'm right in saying that the cache won't be invalidated if a price changes? (I don't have a `modified_at`) – Sam Starling Dec 22 '14 at 10:00
  • Yes that assumption is correct. You didn't mention this in your question though. There does need to be a way to determine if prices have been updated since the last time the fragment was cached. Otherwise, your only option would be to invalidate the cache manually. – fivedigit Dec 22 '14 at 10:08