aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/metal
diff options
context:
space:
mode:
authorclaudiob <claudiob@gmail.com>2015-01-06 12:14:49 -0800
committerclaudiob <claudiob@gmail.com>2015-02-10 17:08:44 -0800
commit050fda020606028acffeaaf79e65d6f595856262 (patch)
treeadd7803df4e0ccf2b53c1ea8bd25ab19b952d79c /actionpack/lib/action_controller/metal
parent17d9996c91918df4c32b8ed7c67c2bbe715cfc9d (diff)
downloadrails-050fda020606028acffeaaf79e65d6f595856262.tar.gz
rails-050fda020606028acffeaaf79e65d6f595856262.tar.bz2
rails-050fda020606028acffeaaf79e65d6f595856262.zip
Accept a collection in fresh_when and stale?
The methods `fresh_when` and `stale?` from ActionController::ConditionalGet accept a single record as a short form for a hash. For instance ```ruby def show @article = Article.find(params[:id]) fresh_when(@article) end ``` is just a short form for: ```ruby def show @article = Article.find(params[:id]) fresh_when(etag: @article, last_modified: @article.created_at) end ``` This commit extends `fresh_when` and `stale?` to also accept a collection of records, so that a short form similar to the one above can be used in an `index` action. After this commit, the following code: ```ruby def index @article = Article.all fresh_when(etag: @articles, last_modified: @articles.maximum(:created_at)) end ``` can be simply written as: ```ruby def index @article = Article.all fresh_when(@articles) end ```
Diffstat (limited to 'actionpack/lib/action_controller/metal')
-rw-r--r--actionpack/lib/action_controller/metal/conditional_get.rb46
1 files changed, 36 insertions, 10 deletions
diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb
index 3a5929adef..28f0b6e349 100644
--- a/actionpack/lib/action_controller/metal/conditional_get.rb
+++ b/actionpack/lib/action_controller/metal/conditional_get.rb
@@ -57,15 +57,25 @@ module ActionController
# This will render the show template if the request isn't sending a matching ETag or
# If-Modified-Since header and just a <tt>304 Not Modified</tt> response if there's a match.
#
- # You can also just pass a record where +last_modified+ will be set by calling
- # +updated_at+ and the +etag+ by passing the object itself.
+ # You can also just pass a record. In this case +last_modified+ will be set
+ # by calling +updated_at+ and +etag+ by passing the object itself.
#
# def show
# @article = Article.find(params[:id])
# fresh_when(@article)
# end
#
- # When passing a record, you can still set whether the public header:
+ # You can also pass an object that responds to +maximum+, such as a
+ # collection of active records. In this case +last_modified+ will be set by
+ # calling +maximum(:updated_at)+ on the collection (the timestamp of the
+ # most recently updated record) and the +etag+ by passing the object itself.
+ #
+ # def index
+ # @articles = Article.all
+ # fresh_when(@articles)
+ # end
+ #
+ # When passing a record or a collection, you can still set the public header:
#
# def show
# @article = Article.find(params[:id])
@@ -77,8 +87,8 @@ module ActionController
#
# before_action { fresh_when @article, template: 'widgets/show' }
#
- def fresh_when(record = nil, etag: record, last_modified: nil, public: false, template: nil)
- last_modified ||= record.try(:updated_at)
+ def fresh_when(object = nil, etag: object, last_modified: nil, public: false, template: nil)
+ last_modified ||= object.try(:updated_at) || object.try(:maximum, :updated_at)
if etag || template
response.etag = combine_etags(etag: etag, last_modified: last_modified,
@@ -121,8 +131,8 @@ module ActionController
# end
# end
#
- # You can also just pass a record where +last_modified+ will be set by calling
- # +updated_at+ and the +etag+ by passing the object itself.
+ # You can also just pass a record. In this case +last_modified+ will be set
+ # by calling +updated_at+ and +etag+ by passing the object itself.
#
# def show
# @article = Article.find(params[:id])
@@ -135,7 +145,23 @@ module ActionController
# end
# end
#
- # When passing a record, you can still set whether the public header:
+ # You can also pass an object that responds to +maximum+, such as a
+ # collection of active records. In this case +last_modified+ will be set by
+ # calling +maximum(:updated_at)+ on the collection (the timestamp of the
+ # most recently updated record) and the +etag+ by passing the object itself.
+ #
+ # def index
+ # @articles = Article.all
+ #
+ # if stale?(@articles)
+ # @statistics = @articles.really_expensive_call
+ # respond_to do |format|
+ # # all the supported formats
+ # end
+ # end
+ # end
+ #
+ # When passing a record or a collection, you can still set the public header:
#
# def show
# @article = Article.find(params[:id])
@@ -155,8 +181,8 @@ module ActionController
# super if stale? @article, template: 'widgets/show'
# end
#
- def stale?(record = nil, etag: record, last_modified: nil, public: nil, template: nil)
- fresh_when(record, etag: etag, last_modified: last_modified, public: public, template: template)
+ def stale?(object = nil, etag: object, last_modified: nil, public: nil, template: nil)
+ fresh_when(object, etag: etag, last_modified: last_modified, public: public, template: template)
!request.fresh?(response)
end