Method: ActionController::ConditionalGet#stale?

Defined in:
actionpack/lib/action_controller/metal/conditional_get.rb

#stale?(object = nil, **freshness_kwargs) ⇒ Boolean

Sets the etag and/or last_modified on the response and checks them against the request. If the request doesn’t match the provided options, it is considered stale, and the response should be rendered from scratch. Otherwise, it is fresh, and a 304 Not Modified is sent.

Options

See #fresh_when for supported options.

Examples

def show
  @article = Article.find(params[:id])

  if stale?(etag: @article, last_modified: @article.updated_at)
    @statistics = @article.really_expensive_call
    respond_to do |format|
      # all the supported formats
    end
  end
end

You can also just pass a record:

def show
  @article = Article.find(params[:id])

  if stale?(@article)
    @statistics = @article.really_expensive_call
    respond_to do |format|
      # all the supported formats
    end
  end
end

etag will be set to the record, and last_modified will be set to the record’s updated_at.

You can also pass an object that responds to maximum, such as a collection of records:

def index
  @articles = Article.all

  if stale?(@articles)
    @statistics = @articles.really_expensive_call
    respond_to do |format|
      # all the supported formats
    end
  end
end

In this case, etag will be set to the collection, and last_modified will be set to maximum(:updated_at) (the timestamp of the most recently updated record).

When passing a record or a collection, you can still specify other options, such as :public and :cache_control:

def show
  @article = Article.find(params[:id])

  if stale?(@article, public: true, cache_control: { no_cache: true })
    @statistics = @articles.really_expensive_call
    respond_to do |format|
      # all the supported formats
    end
  end
end

The above will set Cache-Control: public, no-cache in the response.

When rendering a different template than the controller/action’s default template, you can indicate which digest to include in the ETag:

def show
  super if stale?(@article, template: "widgets/show")
end

Returns:

  • (Boolean)


227
228
229
230
# File 'actionpack/lib/action_controller/metal/conditional_get.rb', line 227

def stale?(object = nil, **freshness_kwargs)
  fresh_when(object, **freshness_kwargs)
  !request.fresh?(response)
end