Search code examples
ruby-on-rails-3cachingcache-digests

Rails cache_digests and conditionals


When we cache a partial in rails using cache digests, how does the conditional logic in the partial get handled? Does it cache the full template and later apply the conditionals so that the right json/html can be served to the right user?


Solution

  • Does it cache the full template and later apply the conditionals so that the right json/html can be served to the right user?

    This part of question seems a bit unclear to me, so I'll provide different options based on what "conditionals" could be.

    First of all, cache digests do not care about inner conditions based on @variables's state (unless a particular state is mentioned inside of its cache key). Consider the following example:

    # users.haml
    .welcome_block
      - if @user.admin?
        %h4 Hello, admin!
      - else
        %h4 Hello, user!
    

    In case you apply caching to the whole page with cache ['users_haml'], the cache would be generated just once (for the first user with whichever role). Any user who accessed this page later would see the same h4 greeting as the one which has been shown to the first user. The reason here is that digest for string users_haml, proved to cache method, is always the same regardless of any circumstances.

    On the other hand, cache @user would provide slightly different behaviour. Each user who opens users.haml page would see proper greeting based on his/her role. The reason for this behaviour is that digest differs for all objects of type User, so cache_digests generates N cached pages for N users.

    The last one kind of conditionals which comes to mind is the one based on conditional partials rendering, e.g.:

    # users.haml
    - cache [@user.month_of_birth]
      - if @user.month_of_birth == 'October'
        = render 'partial_one'
      - else
        = render 'partial_two'
    

    So, this one renders correct cached page for users with different months of birth. But what should happen if I change the contents of partial_one? How does cache_digests understand that cache should be invalidated for those who were born in october (based on the conditional statement)?

    The answer here is that it doesn't know that at all. The only thing it knows is that users.haml depends on both partial_one and partial_two, so changes to either of these inner partials gonna invalidate ALL the users.haml page caches regardless of users' month of birth.