Rails如何传递User对象到TestsController关联创建用户所属测试
Rails跨控制器传递用户ID创建关联记录方案
核心实现思路
跨控制器传递轻量标识(如用户ID)直接通过HTTP请求参数携带即可,注意必须做参数合法性校验,避免非法参数生成脏数据。
分步修改代码
1. 调整跳转逻辑,携带用户ID参数
你目前的start_test中转动作可以直接在重定向时拼接参数,也可以直接跳过该中转动作减少一次请求:
方式A:保留start_test动作的写法
修改UsersController的重定向逻辑:
class UsersController < ApplicationController def show @user = User.find(1) end def start_test # 重定向时将用户ID作为查询参数传递 redirect_to tests_path(user_id: @user.id) end end
方式B:去掉冗余中转动作(推荐)
直接修改show.html.erb的按钮代码,直接跳转到tests路径并携带参数,注意button_to默认发POST请求,index动作是GET路由,需要指定请求方法:
<p>Welcome <%= @user.name %>!</p> <%= button_to "Start Test", tests_path(user_id: @user.id), method: :get %>
这种写法可以删掉UsersController里多余的start_test动作,简化路由配置。
2. 在TestsController中接收参数创建关联记录
不要直接拿参数拼外键创建,先校验用户存在性,通过模型关联创建记录自动绑定外键:
class TestsController < ApplicationController def index # 先根据传入ID查找用户,ID不存在时自动返回404错误,避免脏数据 @user = User.find(params[:user_id]) # 通过has_many关联创建测试,自动填充user_id外键 @test = @user.tests.create! # 你的后续业务逻辑,比如跳转到答题页 redirect_to test_questions_path(@test) end end
后续优化提示
等你后续完成用户登录功能后,禁止从前端参数传递user_id,直接从服务端会话(session)中读取当前登录用户ID即可,彻底避免用户篡改参数越权创建其他用户的测试记录,示例逻辑:
# 登录后从session取用户,不需要前端传参 @user = User.find(session[:current_user_id]) @test = @user.tests.create!
内容的提问来源于stack exchange,提问作者Acheese
相关产品推荐
相关产品推荐

