Rails: Composing an ETag from multiple records

Posted . Visible to the public. Repeats.

Rails offers the fresh_when method to automatically compute an ETag from the given record, array of records or scope of records:

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
    fresh_when @user
  end  
  
  
  def index
    @users = User.all.to_a
    fresh_when @users
  end
end

When your view also displays other records (typically associations), those other records should be included in the ETag. You can do so by passing an array of ETaggable objects to fresh_when.

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])

    # The show template also renders the user's posts.
    fresh_when [@user, *@user.posts]
  end  
  
  
  def index
    @users = User.all.preload(:group).to_a

    # The index template also renders the user's group.
    fresh_when [*@users, *@users.map(&:group)]
  end
end

When you find yourself mixing in the same ETag inputs in all actions, you may also use a controller-wide etag { ... } block:

class UsersController < ApplicationController
  etag { current_user } # Mix the current user into the ETag of all actions
  
  def show
    ...
  end
  
  def index
    ...
  end
end

Read more

Henning Koch
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2023-04-14 13:29)