You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:57:16