Rails7升级后render_to_string触发ActionView::MissingTemplate异常
问题根因
直接看抛出的异常信息里的formats=>[:pdf]字段就能定位核心原因:Rails 7 修改了render_to_string方法的默认格式继承逻辑,Rails 6 环境下该方法会自动兼容匹配html格式模板,Rails 7 则会严格继承当前请求的响应格式做模板查找。你当前触发报错的action是处理pdf格式请求的,调用方法时默认只会查找后缀为.pdf的对应模板,自然找不到你指定的.html.erb模板,最终抛出ActionView::MissingTemplate异常。
可行解决方案
任选一种方式修改即可,优先选第一种,影响范围最小:
- 显式指定渲染格式:调用
render_to_string时新增formats: [:html]参数,强制方法按html格式查找目标模板,修改后的代码如下:
class SomethingController < ApplicationController ... def my_action html_string = render_to_string( template: 'something/template.html.erb', locals: {id: params[:id]}, formats: [:html] ) end end
- 如果你需要在这个action内多次渲染html模板,也可以在执行渲染逻辑前临时修改当前请求的格式属性,不过这种方式会影响同action内后续的渲染逻辑,非必要不推荐。
- 注意:哪怕你把template参数里的文件后缀去掉,简写为
something/template,只要不指定formats参数,还是会按当前请求的pdf格式查找模板,依然会报错。
通用排查思路
后续再遇到Rails升级后的模板找不到异常,优先核对异常信息里的三个核心字段,能快速定位90%以上的问题:
formats:确认当前模板查找使用的格式,和你实际存放的模板文件后缀是否匹配,这是跨大版本升级最容易出现兼容问题的点Searched in:确认你的目标模板文件确实存放在列出的视图查找路径下,没有放错目录层级handlers:确认模板后缀对应的渲染处理器已经被正确加载,比如erb模板需要对应的erb处理器在列表中才会被识别
内容的提问来源于stack exchange,提问作者Rogerio Nascimento
相关产品推荐
相关产品推荐

