Prefer caching views over objects

Caching Rails query objects can lead to issues when upgrading Rails, as changes in the framework may invalidate cached objects. Caching query objects is also ineffective because it is cached before it is executed. Instead, prefer caching objects, data or, even better, views directly.

Avoid Caching Query Objects πŸ”—

Bad (-) Good (+) πŸ”—

  def show
    @posts = Rails.cache.fetch(params[:id], "posts_query", expires_in: 12.hours) do
-     @user.posts # This will ineffectively cache the ActiveRecord query object
+     @user.posts.to_a # This will effectively cache the result of the query
    end
  end

Prefer View Caching πŸ”—

Where possible, it’s best to use view caching rather than object caching. Objects that are cached may be serialized in a way that is incompatible with subsequent changes to a model. Later versions of the app may try to deserialize these objects in invalid states. This most often causes problems when either Rails is upgraded or a migration causes a column to be removed or changed. It’s also a difficult problem to diagnose because the errors usually occur in cached Rails internals.

Bad (-) Good (+) πŸ”—

  # In the controller
  def show
-   @posts = Rails.cache.fetch(params[:id], "posts_query", expires_in: 12.hours) do
-     @user.posts.to_a
-   end
+   @posts = @user.posts
  end

  # In the view
- <%= render @posts %>
+ <% cache [params[:id], "posts"], expires_in: 12.hours do %>
+   <%= render @posts %>
+ <% end %>

Resources πŸ”—