diff options
author | claudiob <claudiob@gmail.com> | 2015-01-06 12:14:49 -0800 |
---|---|---|
committer | claudiob <claudiob@gmail.com> | 2015-02-10 17:08:44 -0800 |
commit | 050fda020606028acffeaaf79e65d6f595856262 (patch) | |
tree | add7803df4e0ccf2b53c1ea8bd25ab19b952d79c /actionpack/lib | |
parent | 17d9996c91918df4c32b8ed7c67c2bbe715cfc9d (diff) | |
download | rails-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')
-rw-r--r-- | actionpack/lib/action_controller/metal/conditional_get.rb | 46 |
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 |