mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Bring back support for callable cache_key on collection rendering
This commit is contained in:
parent
b334c19c07
commit
714c763dad
3 changed files with 30 additions and 5 deletions
|
@ -393,9 +393,14 @@ class CollectionCacheController < ActionController::Base
|
|||
@customers = [Customer.new('david', 1)]
|
||||
render partial: 'customers/commented_customer', collection: @customers, as: :customer, cached: true
|
||||
end
|
||||
|
||||
def index_with_callable_cache_key
|
||||
@customers = [Customer.new('david', 1)]
|
||||
render partial: 'customers/customer', collection: @customers, cached: -> customer { 'cached_david' }
|
||||
end
|
||||
end
|
||||
|
||||
class AutomaticCollectionCacheTest < ActionController::TestCase
|
||||
class CollectionCacheTest < ActionController::TestCase
|
||||
def setup
|
||||
super
|
||||
@controller = CollectionCacheController.new
|
||||
|
@ -438,6 +443,11 @@ class AutomaticCollectionCacheTest < ActionController::TestCase
|
|||
assert_equal 1, @controller.partial_rendered_times
|
||||
end
|
||||
|
||||
def test_caching_with_callable_cache_key
|
||||
get :index_with_callable_cache_key
|
||||
assert_customer_cached 'cached_david', 'david, 1'
|
||||
end
|
||||
|
||||
private
|
||||
def assert_customer_cached(key, content)
|
||||
assert_match content,
|
||||
|
|
|
@ -130,9 +130,10 @@ module ActionView
|
|||
#
|
||||
# When rendering a collection of objects that each use the same partial, a `cached`
|
||||
# option can be passed.
|
||||
#
|
||||
# For collections rendered such:
|
||||
#
|
||||
# <%= render partial: 'notifications/notification', collection: @notifications, cached: true %>
|
||||
# <%= render partial: 'projects/project', collection: @projects, cached: true %>
|
||||
#
|
||||
# The `cached: true` will make Action View's rendering read several templates
|
||||
# from cache at once instead of one call per template.
|
||||
|
@ -142,13 +143,21 @@ module ActionView
|
|||
# Works great alongside individual template fragment caching.
|
||||
# For instance if the template the collection renders is cached like:
|
||||
#
|
||||
# # notifications/_notification.html.erb
|
||||
# <% cache notification do %>
|
||||
# # projects/_project.html.erb
|
||||
# <% cache project do %>
|
||||
# <%# ... %>
|
||||
# <% end %>
|
||||
#
|
||||
# Any collection renders will find those cached templates when attempting
|
||||
# to read multiple templates at once.
|
||||
#
|
||||
# If your collection cache depends on multiple sources (try to avoid this to keep things simple),
|
||||
# you can name all these dependencies as part of a block that returns an array:
|
||||
#
|
||||
# <%= render partial: 'projects/project', collection: @projects, cached: -> project { [ project, current_user ] } %>
|
||||
#
|
||||
# This will include both records as part of the cache key and updating either of them will
|
||||
# expire the cache.
|
||||
def cache(name = {}, options = {}, &block)
|
||||
if controller.respond_to?(:perform_caching) && controller.perform_caching
|
||||
name_options = options.slice(:skip_digest, :virtual_path)
|
||||
|
|
|
@ -25,9 +25,15 @@ module ActionView
|
|||
end
|
||||
end
|
||||
|
||||
def callable_cache_key?
|
||||
@options[:cached].respond_to?(:call)
|
||||
end
|
||||
|
||||
def collection_by_cache_keys
|
||||
seed = callable_cache_key? ? @options[:cached] : ->(i) { i }
|
||||
|
||||
@collection.each_with_object({}) do |item, hash|
|
||||
hash[expanded_cache_key(item)] = item
|
||||
hash[expanded_cache_key(seed.call(item))] = item
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue