A lot has been written about Russian Doll Caching in Rails 4 but surprisingly little about caching of collections. One of the basic tenets is that you should use “touch: true” on your “belongs_to” relationships in order to update the “updated_at” time on the parent record and thus invalidate its cached copies.
The problem here is that if an item is updated it won’t change the updated_at date on the project_items that are associated with it, nor do we want it to. But we need to invalidate both the main Project cache and the individual Item cache. Simply changing the cache key on the second item to “project_item.item” doesn’t fix this as the Project still won’t be updated.
What is the proper cache key for the outer @project cache?
What is the proper cache key for the inner item cache?
And that mostly works. The problem is that the cache key will simply grow as items are added. What might not be a problem with two or three items gets out of whack with 50 or 100. I’ve seen cache keys that are a block of 10+ lines at 80 characters wide. That’s inefficient.
Now, the question is how best to do this. That’s a little ugly.
With that, it’ll get @project.items.cache_key and the cache will be invalidated if any item is updated. The bonus is that the cache key is made up of only a few items and is much more manageable. It’s also much more readable to humans, both in code and in the cache itself.
That way any update to either the project_item or the item will invalidate the cache. I found a gem that should add the cache_key for associations but it seems to not work with Rails 4. It would be useful for someone to update it as this functionality is even better when the code doesn’t have to be specified each time.
The argument for being non-DRY is that some cache key schemes might be lighter-weight and work for some places. The example here is another table that contains viewing logs for projects. The table is basically write-only, never updated. So I can just look at the record count or maximum id on the joined table to determine the cache key. Etc.