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/CHANGELOG.md | 11 +++++++++++ actionview/lib/action_view/renderer/partial_renderer.rb | 3 ++- actionview/test/template/render_test.rb | 8 ++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index ab4b46c56e..987d062540 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,14 @@ +* Changed partial rendering with a collection to allow collections which + don't implement `to_ary`. + + Extracting the collection option has an optimization to avoid unnecessary + queries of ActiveRecord Relations by calling `to_ary` on the given + collection. Instances of `Enumerator` or `Enumerable` are valid + collections, but they do not implement `#to_ary`. They will now be + extracted and rendered as expected. + + *Steven Harman* + * New syntax for tag helpers. Avoid positional parameters and support HTML5 by default. Example usage of tag helpers before: 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 diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb index 25b21850b1..e991fae491 100644 --- a/actionview/test/template/render_test.rb +++ b/actionview/test/template/render_test.rb @@ -309,6 +309,14 @@ module RenderTestCases assert_nil @view.render(:partial => "test/customer", :collection => nil) end + def test_render_partial_collection_for_non_array + customers = Enumerator.new do |y| + y.yield(Customer.new("david")) + y.yield(Customer.new("mary")) + end + assert_equal "Hello: davidHello: mary", @view.render(:partial => "test/customer", collection: customers) + end + def test_render_partial_without_object_does_not_put_partial_name_to_local_assigns assert_equal 'false', @view.render(partial: 'test/partial_name_in_local_assigns') end -- cgit v1.2.3