max
max

Reputation: 101811

Rails caching gives wrong response format

I am using ETag caching for a Rails (4.1.1) action with the stale? method; however it does not take the request format into consideration. Example: if /stations.json has been loaded by the user and they then click a link to /stations they will get a cached JSON response instead of html.

Am I doing it wrong or is this a Rails bug?

# GET /stations
# GET /stations.json
def index
  @title = "Stations"
  @last_updated = Station.order("updated_at asc").last

  if stale?(@last_updated, last_modified: @last_updated.try(:updated_at))
    @stations = all_with_latest_observation
    respond_to do |format|
      format.html
      format.json { render json: @stations }
    end
  end
end

Upvotes: 0

Views: 240

Answers (2)

max
max

Reputation: 101811

This seems to be a bug in ActionPack

I found a workaround

class ApplicationController 
  etag { request.format }
end

And of course the spec:

describe StationsController do
  describe "GET index" do
    describe "ETag" do
      before { get :index, format: 'json' }
      it "should not use the same ETag for different content types" do
        get :index, format: 'json'
        first_response = response.headers.clone
        get :index, format: 'html'
        expect(first_response['ETag']).to_not eq (response.headers['ETag'])
      end
    end
  end
end

Upvotes: 0

Naim Rajiv
Naim Rajiv

Reputation: 3374

I think you should add the key :etag when you call stale? method.

# GET /stations
# GET /stations.json
def index
 @title = "Stations"
 @last_updated = Station.order("updated_at asc").last

 if stale?(etag: @last_updated, last_modified: @last_updated.try(:updated_at))
   @stations = all_with_latest_observation
   respond_to do |format|
    format.html
    format.json { render json: @stations }
   end
 end
end

Then let's see what's happen!

Upvotes: 1

Related Questions