Skip to content

Commit b033b4c

Browse files
authored
Merge pull request #554 from github/549-collection-private-method-format
Fix bug rendering component collections from controllers
2 parents 274fab0 + dcd76b7 commit b033b4c

File tree

6 files changed

+35
-8
lines changed

6 files changed

+35
-8
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ jobs:
3434
runs-on: ubuntu-latest
3535
strategy:
3636
matrix:
37-
rails_version: [5.0.0, 5.2.3, 6.0.0, master]
37+
rails_version: [5.0.0, 5.2.3, 6.0.0, 6.1.0, master]
3838
ruby_version: [2.4.x, 2.5.x, 2.6.x, 2.7.x]
3939
exclude:
40-
- rails_version: master
41-
ruby_version: 2.4.x
4240
- rails_version: 6.0.0
4341
ruby_version: 2.4.x
42+
- rails_version: 6.1.0
43+
ruby_version: 2.4.x
44+
- rails_version: master
45+
ruby_version: 2.4.x
4446
steps:
4547
- uses: actions/checkout@master
4648
- name: Setup Ruby

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## master
44

5+
* Fix bug where rendering a component `with_collection` from a controller raised an error.
6+
7+
*Joel Hawksley*
8+
59
## 2.23.1
610

711
* Fixed out-of-order rendering bug in `ActionView::SlotableV2`

lib/view_component/collection.rb

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44

55
module ViewComponent
66
class Collection
7+
attr_reader :component
8+
delegate :format, to: :component
9+
710
def render_in(view_context, &block)
811
iterator = ActionView::PartialIteration.new(@collection.size)
912

10-
@component.compile(raise_errors: true)
11-
@component.validate_collection_parameter!(validate_default: true)
13+
component.compile(raise_errors: true)
14+
component.validate_collection_parameter!(validate_default: true)
1215

1316
@collection.map do |item|
14-
content = @component.new(**component_options(item, iterator)).render_in(view_context, &block)
17+
content = component.new(**component_options(item, iterator)).render_in(view_context, &block)
1518
iterator.iterate!
1619
content
1720
end.join.html_safe
@@ -34,8 +37,8 @@ def collection_variable(object)
3437
end
3538

3639
def component_options(item, iterator)
37-
item_options = { @component.collection_parameter => item }
38-
item_options[@component.collection_counter_parameter] = iterator.index + 1 if @component.counter_argument_present?
40+
item_options = { component.collection_parameter => item }
41+
item_options[component.collection_counter_parameter] = iterator.index + 1 if component.counter_argument_present?
3942

4043
@options.merge(item_options)
4144
end

test/app/controllers/integration_examples_controller.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,10 @@ def controller_to_string_render_component
3434
def products
3535
@products = [OpenStruct.new(name: "Radio clock"), OpenStruct.new(name: "Mints")]
3636
end
37+
38+
def inline_products
39+
products = [OpenStruct.new(name: "Radio clock"), OpenStruct.new(name: "Mints")]
40+
41+
render(ProductComponent.with_collection(products, notice: "Today only"))
42+
end
3743
end

test/config/routes.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
get :content, to: "integration_examples#content"
1010
get :variants, to: "integration_examples#variants"
1111
get :products, to: "integration_examples#products"
12+
get :inline_products, to: "integration_examples#inline_products"
1213
get :cached, to: "integration_examples#cached"
1314
get :render_check, to: "integration_examples#render_check"
1415
get :controller_inline, to: "integration_examples#controller_inline"

test/view_component/integration_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,17 @@ def test_renders_collections
330330
assert_select("p", text: "Mints counter: 2")
331331
end
332332

333+
def test_renders_inline_collections
334+
get "/inline_products"
335+
336+
assert_select("h1", text: "Product", count: 2)
337+
assert_select("h2", text: "Radio clock")
338+
assert_select("h2", text: "Mints")
339+
assert_select("p", text: "Today only", count: 2)
340+
assert_select("p", text: "Radio clock counter: 1")
341+
assert_select("p", text: "Mints counter: 2")
342+
end
343+
333344
def test_renders_the_previews_in_the_configured_route
334345
with_preview_route("/previews") do
335346
get "/previews"

0 commit comments

Comments
 (0)