fresh_when
fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, cache_control: {}, template: nil)Sets the `etag`, `last_modified`, or both on the response, and renders a `304 Not Modified` response if the request is already fresh.
#### Options
`:etag` : Sets a “weak” ETag validator on the response. See the `:weak_etag` option.
`:weak_etag` : Sets a “weak” ETag validator on the response. Requests that specify an
`If-None-Match` header may receive a `304 Not Modified` response if the ETag matches exactly.
: A weak ETag indicates semantic equivalence, not byte-for-byte equality, so
they're good for caching HTML pages in browser caches. They can't be used for responses that must be byte-identical, like serving `Range` requests within a PDF file.
`:strong_etag` : Sets a “strong” ETag validator on the response. Requests that specify an
`If-None-Match` header may receive a `304 Not Modified` response if the ETag matches exactly.
: A strong ETag implies exact equality – the response must match byte for
byte. This is necessary for serving `Range` requests within a large video or PDF file, for example, or for compatibility with some CDNs that don't support weak ETags.
`:last_modified` : Sets a “weak” last-update validator on the response. Subsequent requests
that specify an `If-Modified-Since` header may receive a `304 Not Modified` response if `last_modified` <= `If-Modified-Since`.
`:public` : By default the `Cache-Control` header is private. Set this option to
`true` if you want your application to be cacheable by other devices, such as proxy caches.
`:cache_control` : When given, will overwrite an existing `Cache-Control` header. For a list
of `Cache-Control` directives, see the [article on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control).
`:template` : By default, the template digest for the current controller/action is
included in ETags. If the action renders a different template, you can include its digest instead. If the action doesn't render a template at all, you can pass `template: false` to skip any attempt to check for a template digest.
#### Examples
def show @article = Article.find(params[:id]) fresh_when(etag: @article, last_modified: @article.updated_at, public: true) end
This will send a `304 Not Modified` response if the request specifies a matching ETag and `If-Modified-Since` header. Otherwise, it will render the `show` template.
You can also just pass a record:
def show @article = Article.find(params[:id]) fresh_when(@article) 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 fresh_when(@articles) 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]) fresh_when(@article, public: true, cache_control: { no_cache: true }) 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:
before_action { fresh_when @article, template: "widgets/show" }