Skip to content

Commit ae75930

Browse files
committed
Fix collection_from_options to allow Enumerators
An optimization was introduced in rails@27f4ffd 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.
1 parent c59715f commit ae75930

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

actionview/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
* Changed partial rendering with a collection to allow collections which
2+
don't implement `to_ary`.
3+
4+
Extracting the collection option has an optimization to avoid unnecessary
5+
queries of ActiveRecord Relations by calling `to_ary` on the given
6+
collection. Instances of `Enumerator` or `Enumerable` are valid
7+
collections, but they do not implement `#to_ary`. They will now be
8+
extracted and rendered as expected.
9+
10+
*Steven Harman*
11+
112
* New syntax for tag helpers. Avoid positional parameters and support HTML5 by default.
213
Example usage of tag helpers before:
314

actionview/lib/action_view/renderer/partial_renderer.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,8 @@ def setup(context, options, block)
404404
def collection_from_options
405405
if @options.key?(:collection)
406406
collection = @options[:collection]
407-
collection.respond_to?(:to_ary) ? collection.to_ary : []
407+
collection = collection.to_ary if collection.respond_to?(:to_ary)
408+
collection
408409
end
409410
end
410411

actionview/test/template/render_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,14 @@ def test_render_partial_with_nil_collection_should_return_nil
309309
assert_nil @view.render(:partial => "test/customer", :collection => nil)
310310
end
311311

312+
def test_render_partial_collection_for_non_array
313+
customers = Enumerator.new do |y|
314+
y.yield(Customer.new("david"))
315+
y.yield(Customer.new("mary"))
316+
end
317+
assert_equal "Hello: davidHello: mary", @view.render(:partial => "test/customer", collection: customers)
318+
end
319+
312320
def test_render_partial_without_object_does_not_put_partial_name_to_local_assigns
313321
assert_equal 'false', @view.render(partial: 'test/partial_name_in_local_assigns')
314322
end

0 commit comments

Comments
 (0)