Rails7 Devise提交自由职业者注册表单报无用户ID错误
报错根因
ActiveRecord::RecordNotFound (Couldn't find User without an ID) 是因为提交表单触发register_freelancer动作时,params[:id]为nil,执行User.find(params[:id])时无法定位到对应用户记录。
具体触发逻辑:
- 渲染注册表单的
registration_form动作未给@user实例变量赋值,form_with无法生成带用户ID的提交路径 - 配置的POST
/registration_form路由是不带动态:id段的集合路由,提交请求时根本不会携带用户ID参数 - 业务场景为已登录用户给自己升级自由职业者身份,本就不需要通过URL传用户ID,直接使用Devise提供的
current_user获取当前登录用户即可,还能避免越权操作风险
具体修复步骤
- 补全表单页动作的实例变量赋值
修改pages_controller.rb中的registration_form方法,给表单提供当前登录用户对象:def registration_form @user = current_user # 加未登录拦截,避免未登录用户访问报错 redirect_to new_user_session_path unless @user end - 重写自由职业者注册提交逻辑
替换register_freelancer方法,移除从params[:id]查用户的逻辑,直接用current_user操作,同时加上表单校验失败的处理:def register_freelancer @user = current_user redirect_to new_user_session_path and return unless @user if @user.update(seller_params) @user.freelancer! redirect_to root_path, notice: "自由职业者身份开通成功" else # 校验失败返回表单页,保留用户填的内容和错误提示 render :registration_form, status: :unprocessable_entity end end - 清理冗余路由
原路由中resources :pages会自动生成一堆用不到的Pages RESTful路由,和手动声明的路由产生冲突,直接删除即可,最终路由配置:Rails.application.routes.draw do root 'pages#home' devise_for :users get '/home', to: 'pages#home' get '/registration_form', to: 'pages#registration_form' post '/registration_form', to: 'pages#register_freelancer' end
额外优化提示
- 原代码中
@user.update执行后没有判断返回结果就直接调用current_user.freelancer!切换角色,会出现用户资料不符合校验规则(比如bio为空、cost为负数)但身份已经被切换的逻辑bug,上面的修复代码已经处理了这个问题。 - 确保User模型中已经正确配置了角色枚举(比如
enum role: { normal: 0, freelancer: 1 }),否则freelancer!方法无法正常执行。
内容的提问来源于stack exchange,提问作者Luke Czoboriek
相关产品推荐
相关产品推荐

