You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ViewComponent报错:找不到子组件模板文件或内联渲染方法

报错信息
ViewComponent::TemplateError in Welcome#show
Couldn't find a template file or inline render method for FaqComponent::QuestionComponent.

该报错出现于使用view_component gem渲染嵌套组件的场景。

现有代码与配置

组件类定义

文件路径:app/components/faq_component.rb

class FaqComponent < ViewComponent::Base
  renders_many :questions, "QuestionComponent"

  class QuestionComponent < ViewComponent::Base
    attr_reader :question

    def initialize(question: "")
      @question = question
    end
  end
end

父组件模板

文件路径:app/components/faq_component/faq_component.html.erb,报错触发位置为模板中渲染子组件q的行:

<%= content_tag :div, class: "c-faq", data: { controller: "faq" } do %>
  <%= content_tag :div, class: "c-card" do %>
    <% questions.each do |q| %>
      <%= content_tag :div, class: "c-card__section" do %>
        <button class="c-faq__question" data-faq-target="question">
          <%= q.question %>
          <%= icon("arrow-expand", classes: "u-m-0", size: 12) %>
        </button>
        <div class="c-faq__answer">
          <%= q %> <!-- 报错出现在此处 -->
        </div>
      <% end %>
    <% end %>
  <% end %>
<% end %>

页面调用代码

<div class="l-container u-mb-xxl u-xs-mb-l">
  <div class="l-row">
    <div class="l-col-xs-26 l-col-md-24 l-col-md-offset-1">
      <h3 class="u-mb-s">常见问题</h3>
      <%= render(FaqComponent.new) do |faq| %>
        <% faq.question(question: "What is ViewComponent?") do %>
          <p>View component is a pain because it's not working or because I'm using it for the very first time!</p>
        <% end %>
      <% end %>
    </div>
  </div>
</div>
报错原因

ViewComponent 组件的渲染入口只有两种:

  1. 和组件类路径匹配的模板文件
  2. 组件类中定义的#call实例方法作为内联渲染逻辑

当前定义的嵌套类FaqComponent::QuestionComponent既没有对应路径的模板文件,类中也没有定义call方法,框架找不到渲染入口就会抛出该错误。

解决方法

两种方案二选一即可:

  • 方案1(符合常规组件开发规范):创建子组件对应的模板文件
    注意因为QuestionComponent是FaqComponent的内部类,模板不能直接放在app/components根目录,需要放在父组件的同名目录下,路径为app/components/faq_component/question_component.html.erb,模板内容直接输出调用时传入的块内容即可:
    <%= content %>
    
  • 方案2(无需单独模板文件):在子组件类中添加内联渲染的call方法
    修改app/components/faq_component.rb中的QuestionComponent定义:
    class QuestionComponent < ViewComponent::Base
      attr_reader :question
    
      def initialize(question: "")
        @question = question
      end
    
      def call
        content
      end
    end
    

修改完成后重启应用服务即可正常渲染。

内容的提问来源于stack exchange,提问作者rony36

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 18:09:16