From ae75930b59e7b41133c5a62c09da3c02309f81f3 Mon Sep 17 00:00:00 2001 From: Steven Harman Date: Thu, 21 Jul 2016 13:15:59 -0400 Subject: Fix collection_from_options to allow Enumerators An optimization was introduced in https://github.com/rails/rails/commit/27f4ffd11a91b534fde9b484cb7c4e515ec0fe77 which tried to `#to_ary` the collection to prevent unnecessary queries for ActiveRecord scopes/relations. If the given collection did not respond to `#to_ary`, and empty collection was returned. That meant you couldn't use collections built from `Enumerator` nor `Enumerable`. With this change, `#collection_from_options` will attempt the optimization, but fall back to passing along the given collection, as-is. --- actionview/lib/action_view/renderer/partial_renderer.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'actionview/lib/action_view') diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index c2b15e72e9..1b28c180e3 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -404,7 +404,8 @@ module ActionView def collection_from_options if @options.key?(:collection) collection = @options[:collection] - collection.respond_to?(:to_ary) ? collection.to_ary : [] + collection = collection.to_ary if collection.respond_to?(:to_ary) + collection end end -- cgit v1.2.3 From e4a4936244988f76318a0b219a3cc0bcdcdf3e30 Mon Sep 17 00:00:00 2001 From: Steven Harman Date: Tue, 26 Jul 2016 10:37:10 -0400 Subject: Default to an empty collection if falsey given This will ensure we attempt to render an empty collection, meaning we don't actually render anything at all. Allowing `nil` or a falsey value through results in calling `render_partial` rather than `render_collection`, which isn't what we want. --- actionview/lib/action_view/renderer/partial_renderer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionview/lib/action_view') diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index 1b28c180e3..c2b6e6a290 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -403,7 +403,7 @@ module ActionView def collection_from_options if @options.key?(:collection) - collection = @options[:collection] + collection = @options[:collection] || [] collection = collection.to_ary if collection.respond_to?(:to_ary) collection end -- cgit v1.2.3 From 87899cfcf0ada140764acf4393eb862698449f54 Mon Sep 17 00:00:00 2001 From: Steven Harman Date: Tue, 26 Jul 2016 11:28:03 -0400 Subject: Use to_a to pre-buffer the collection We can safely assume we're not dealing with an infinite collection as we're about to call `each` on it and collect the results until it terminates on its own. Given that, `to_a` is implemented by the normal Array-like objects, and less Array-like objects like `Enumerator` and `Enumerator::Lazy`. --- actionview/lib/action_view/renderer/partial_renderer.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'actionview/lib/action_view') diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index c2b6e6a290..7c2e07185c 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -403,9 +403,8 @@ module ActionView def collection_from_options if @options.key?(:collection) - collection = @options[:collection] || [] - collection = collection.to_ary if collection.respond_to?(:to_ary) - collection + collection = @options[:collection] + collection ? collection.to_a : [] end end -- cgit v1.2.3