Skip to content

Commit

Permalink
Fix collection_from_options to allow Enumerators
Browse files Browse the repository at this point in the history
An optimization was introduced in
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.
  • Loading branch information
stevenharman committed Jul 26, 2016
1 parent c59715f commit ae75930
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
11 changes: 11 additions & 0 deletions 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:

Expand Down
3 changes: 2 additions & 1 deletion actionview/lib/action_view/renderer/partial_renderer.rb
Expand Up @@ -404,7 +404,8 @@ def setup(context, options, block)
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

Expand Down
8 changes: 8 additions & 0 deletions actionview/test/template/render_test.rb
Expand Up @@ -309,6 +309,14 @@ def test_render_partial_with_nil_collection_should_return_nil
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
Expand Down

0 comments on commit ae75930

Please sign in to comment.