Rails 7中Devise注册页面表单错误未渲染问题求助
解决Rails 7 + Devise注册表单错误不渲染的Turbo报错问题
问题根源
Turbo要求表单提交的响应要么是重定向,要么返回turbo_stream格式。Devise默认处理注册失败时,会直接返回200状态码并渲染注册页面,这不符合Turbo的规则,所以触发了Form responses must redirect to another location错误;而登录页因Devise内部对登录失败的响应逻辑适配了Turbo,所以能正常渲染错误。
解决方案
1. 自定义Devise注册控制器
在app/controllers/users/registrations_controller.rb创建自定义控制器,重写create方法,失败时返回turbo_stream渲染表单:
class Users::RegistrationsController < Devise::RegistrationsController respond_to :html, :turbo_stream def create build_resource(sign_up_params) resource.save yield resource if block_given? if resource.persisted? if resource.active_for_authentication? set_flash_message! :notice, :signed_up sign_up(resource_name, resource) respond_with resource, location: after_sign_up_path_for(resource) else set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}" expire_data_after_sign_in! respond_with resource, location: after_inactive_sign_up_path_for(resource) end else clean_up_passwords resource set_minimum_password_length # 关键:失败时按请求格式返回响应,适配Turbo respond_with resource, formats: request.format end end end
2. 更新Devise路由
在config/routes.rb中指定自定义注册控制器:
devise_for :users, controllers: { registrations: 'users/registrations' }
3. 确认Devise导航格式配置
在config/initializers/devise.rb中确保导航格式包含turbo_stream:
config.navigational_formats = ['*/*', :html, :turbo_stream]
4. 调整注册页面表单结构
在app/views/devise/registrations/new.html.erb中,将表单包裹在turbo_frame_tag里,确保Turbo能正确更新页面:
<%= turbo_frame_tag 'registration_form' do %> <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= devise_error_messages! %> <!-- 表单字段 --> <%= f.email_field :email, autofocus: true, autocomplete: "email" %> <%= f.password_field :password, autocomplete: "new-password" %> <%= f.password_field :password_confirmation, autocomplete: "new-password" %> <%= f.submit "Sign up" %> <% end %> <% end %>
完成以上步骤后,注册表单验证失败时,控制器会返回符合Turbo要求的响应,页面能正常渲染错误提示,控制台报错也会消失。
内容的提问来源于stack exchange,提问作者Jared Peter
相关产品推荐
相关产品推荐

