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

Rails 7调用render_to_string触发turbo-rails NoMethodError错误求解决

环境信息
Ruby version 3.2.2
Rails version 7.0.8
Gemfile 内容
source 'https://rubygems.org'

ruby '3.2.2'

gem 'rails', '7.0.8'
gem 'puma', '~> 4.3.9'
gem 'sass-rails', '~>6.0.0'
gem 'jquery-rails'
gem 'sprockets', '3.7.2'

# gem 'bootstrap', '~> 5.1.3'

gem 'sprockets-rails'
gem 'turbo-rails'
gem 'stimulus-rails'
gem 'hotwire-rails'
gem 'importmap-rails'
gem 'jsbundling-rails'

gem 'jbuilder', '~> 2.5'
gem 'twilio-ruby', '5.72.1'
gem 'google-authenticator-rails'
gem 'friendly_id', '~> 5.2.0'
gem 'mysql2'

...
错误场景

执行以下irb命令时触发错误:

irb(main):003:0> ActionController::Base.new.render_to_string( template: "shared/file_template/test2" )

错误信息:

/Users/xxx/Documents/projects/rails-project/vendor/cache/ruby/3.2.0/gems/turbo-rails-1.5.0/app/controllers/turbo/frames/frame_request.rb:36:in `turbo_frame_request_id': Could not render layout: undefined method `headers' for nil:NilClass (NoMethodError)

      request.headers["Turbo-Frame"]
             ^^^^^^^^
/Users/xxx/Documents/projects/rails-project/vendor/cache/ruby/3.2.0/gems/turbo-rails-1.5.0/app/controllers/turbo/frames/frame_request.rb:36:in `turbo_frame_request_id': undefined method `headers' for nil:NilClass (NoMethodError)

      request.headers["Turbo-Frame"]
             ^^^^^^^^
修复方案

错误根源是直接实例化ActionController::Base时未初始化request对象,而Turbo Rails的帧处理逻辑依赖request.headers。可通过以下方式解决:

  • 给控制器实例手动注入request对象:
    在调用render_to_string前,为控制器创建有效的request实例:

    controller = ActionController::Base.new
    # 初始化基础request对象
    controller.request = ActionDispatch::Request.new({})
    controller.render_to_string(template: "shared/file_template/test2")
    

    若需要贴近真实请求环境,可使用Rails的env配置:

    controller = ApplicationController.new
    controller.request = ActionDispatch::Request.new(Rails.application.env_config)
    controller.render_to_string(template: "shared/file_template/test2")
    
  • 直接使用ActionView渲染模板:
    绕过控制器的Turbo钩子,直接用视图类渲染模板:

    view = ActionView::Base.new(ActionController::Base.view_paths, {})
    # 如需使用控制器辅助方法,可添加:view.include ApplicationController.helpers
    view.render(template: "shared/file_template/test2")
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 02:42:37