Rails7中Devise结合Turbo表单出现rendering_options未定义错误
Devise适配Rails 7 Turbo表单时验证错误触发未定义方法问题
- 背景:作为开发新手,之前通过方案实现Devise适配Rails 7的Turbo表单,旧项目运行正常,但新项目中注册时不填写字段或输入无效信息,会触发以下错误:
undefined local variable or method 'rendering_options' for #<TurboDeviseController::Responder:0x00007f9684019cb8 @controller=#<Devise::RegistrationsController:0x0000000000bbd0>, @request=#<ActionDispatch::Request POST "http://localhost:3000/users" for ::1>, @format=:turbo_stream, @resource=#<User id: nil, email: "", created_at: nil, updated_at: nil>, @resources=[#<User id: nil, email: "", created_at: nil, updated_at: nil>], @options={}, @action=:new, @default_response=nil> - 已多次复现该错误,旧项目仍正常运行,相关参考文件包括devise控制器文件、devise.rb配置文件、控制台输出、错误截图。
解决方案
这个问题源于Turbo Devise Responder中引用了不存在的rendering_options变量,大概率是新旧项目的Devise、Turbo版本差异导致的,可按以下步骤修复:
修改自定义Responder代码
在你的TurboDeviseController的Responder类中,替换掉rendering_options相关逻辑,改用@options传递渲染参数:class TurboDeviseController < DeviseController class Responder < Devise::Responder def to_turbo_stream controller.render(@options.merge(formats: :html)) { |format| format.html { render template: "#{controller_name}/#{action}" } } rescue ActionView::MissingTemplate => e if redirect_to_path redirect_to redirect_to_path else super end end end self.responder = Responder respond_to :html, :turbo_stream end对齐依赖版本
对比旧项目的Gemfile.lock,将新项目的Devise、Turbo、Rails版本调整为和旧项目一致,版本差异是这类问题的常见诱因。直接在控制器处理Turbo流
如果修改Responder无效,可以直接在Devise注册控制器中手动处理验证失败的Turbo渲染:class RegistrationsController < Devise::RegistrationsController respond_to :html, :turbo_stream def create super do |resource| if resource.errors.any? render turbo_stream: turbo_stream.replace('new_user', partial: 'devise/registrations/new', locals: { resource: resource }) end end end end
内容的提问来源于stack exchange,提问作者Rohan James
相关产品推荐
相关产品推荐

