Skip to content

Commit 85efdd8

Browse files
committed
fix inheritance edge case with formatless templates
1 parent dbc6096 commit 85efdd8

7 files changed

Lines changed: 33 additions & 0 deletions

File tree

docs/CHANGELOG.md

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

1111
## main
1212

13+
* Fix bug where inheritance of components with formatless templates improperly raised a NoMethodError.
14+
15+
*GitHub Copilot*, *Joel Hawksley*, *Cameron Dutro*
16+
1317
## 4.6.0
1418

1519
* Add `view_identifier` to the `render.view_component` instrumentation event payload, containing the path to the component's template file (e.g. `app/components/my_component.html.erb`). For components using inline render methods, `view_identifier` will be `nil`.

lib/view_component/template.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ def initialize(component:, details:, lineno: nil, path: nil)
2121

2222
class File < Template
2323
def initialize(component:, details:, path:)
24+
# If the template file has no format (e.g. .erb instead of .html.erb),
25+
# assume the default format (html).
26+
if details.format.nil?
27+
Kernel.warn("Template format for #{path} is missing, defaulting to :html.")
28+
details = ActionView::TemplateDetails.new(details.locale, details.handler, DEFAULT_FORMAT, details.variant)
29+
end
30+
2431
@strip_annotation_line = false
2532

2633
# Rails 8.1 added a newline to compiled ERB output (rails/rails#53731).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div class="child"><%= content %></div>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# frozen_string_literal: true
2+
3+
class FormatLessChildComponent < FormatLessParentComponent
4+
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div class="parent"><%= content %></div>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# frozen_string_literal: true
2+
3+
class FormatLessParentComponent < ViewComponent::Base
4+
end

test/sandbox/test/rendering_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,18 @@ def test_inherited_component_overrides_inherits_template
852852
assert_selector("div", text: "hello, my own template")
853853
end
854854

855+
def test_inherited_component_with_format_less_template
856+
# Reproduces https://github.com/ViewComponent/view_component/issues/2573
857+
# When a parent component uses a format-less template (e.g. .erb or .slim
858+
# instead of .html.erb or .html.slim), the child component crashes with
859+
# "undefined method 'upcase' for nil" during compilation.
860+
render_inline(FormatLessChildComponent.new) do
861+
"Hello World"
862+
end
863+
864+
assert_selector("div.child", text: "Hello World")
865+
end
866+
855867
def test_inherited_inline_component_inherits_inline_method
856868
render_inline(InlineInheritedComponent.new)
857869

0 commit comments

Comments
 (0)