Skip to main content

Russian Doll Caching with Rails 5 Discussion

General • Asked by Chris Oliver

Hey Chris, thank you for this screencast! Cache toggling feature looks awesome (I just learned it from this video). One quick question, do you recommend Redis over Memcached as a cache store?

I do usually recommend Redis most often and the reason for that is simple: You're probably already using it to run your background jobs with Sidekiq or the like, so you might as well just take advantage of that. You can run a separate Memcached instance but I don't think you're going to see a major difference unless there is a feature you specifically need from it that Redis doesn't provide. Basecamp uses Redis for caching, so that means it's definitely good to go. :)

Thanks Chris! I'll look into that option. Good to know that Basecamp is using Redis as the cache store. Thanks, I'm really enjoying this performance related series :)

Would you be up for connecting the same Redis as the cache store and sidekiq? I've ran into issues with this in the past.

What were the issues you ran into? The key names should be scoped accordingly, but other than that, you shouldn't have any issues sharing it.


Nice tutorial Chris! I've got 2 questions and would be nice to know your opinion.

What do you think about using

<% cache ['lists-index', @lists.map(&:id), @lists.map(&:updated_at).max] do %>

instead of

<% cache ['lists-index', "page-#{params[:page] || 1}", @lists.count, @lists.map(&:updated_at).max] do %>

?

Could you also take a look at this question from the recent questions thread? In many situations there are some parts of the page that depend on the user's role (current_user, etc.). I would like to know what approaches can be used in those cases.

Thanks!

Yeah, you could probably do that too with the cache key. There are a lot of different ways to set it up, your goal is really just to make sure that the key gets updated when your database changes and that it only updates when needed. Sometimes that will depend on your app and certain cache keys will make more sense than others.

I'm hopping into the forum this morning to answer a bunch!


Hey Chris. Do you have any tips on expiring childrens when parent changes, where simple touching doesn't apply. Imagine a table of students and their related classes. You cache row fragments. When name of the class changes, rarely, but can, you have to expire all student fragments of the changed class.

Most cases like that, if you include both items in the cache key (both the user and the class) and use their updated_at timestamps there, it will do the trick. That way your cache changes anytime you update one or the other.


Great job on this one. I've been wanting this feature for years. For multi-tenant apps that are setup using Postgres schema's, would it be best to override the cache key to include the tenant id so that it's totally not possible for Todo number 5 in tenant 1 to overlap with Todo number 5 in tenant 2? I know the updated_at makes this a remote possibility, BUT it's still possible. Thoughts?

Yep, you'd need to include that in the cache key so they are all separated out cleanly. Don't want to be leaking any of that information between schemas.


Awesome episode as always Chris.

What about the implications of using roles for some content within a partial that is cached? E.g. say I have a section that I only want to show to `current_user.has_role? :teacher`, but another user that doesn't have the role teacher is also viewing that page at the same time.

How does the built-in Russian Doll Caching stuff play with that scenario?

Edit: Actually Chris, I see that you did that already in the 'Advanced Caching with User Permissions and Authorization' epsiode. Thanks much and pleas ignore this question :)

Yup, you can either use JS to hide / show functionality or you can also include the role in the cache key if you want. That will create caches for each role meaning you'll use more cache storage, but can cache each version separately. I'd still recommend using JS to hide / show things so you only have one cache per item.


How would I cache content different for non-logged in users, logged in users, and the post owner? For example, Facebook "friends" can see your private posts.


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 24,647+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.