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

Rails项目无法按指定格式从数据库获取检查数据求助

Rails数据查询格式问题排查与解决

问题背景

我有一个Rails应用,包含3个模型,无法按所需格式从数据库获取数据。

Rails模型

  • Investigation:id, name, created_at, updated_at
  • Appointment:id, patient_id, investigation_date, ...
  • Result:investigation_id, appointment_id, findings

模型关联

  • Appointment has_many :results
  • Result belongs_to :appointment,Result belongs_to :investigation

表结构片段

create_table "appointments", charset: "utf8mb4", force: :cascade do |t|
  t.bigint "patient_id", null: false
  t.date "investigation_date"
end

create_table "results", charset: "utf8mb4", force: :cascade do |t|
  t.bigint "appointment_id", null: false
  t.bigint "investigation_id", null: false
  t.string "findings"
end

create_table "investigations", charset: "utf8mb4", force: :cascade do |t|
  t.string "name"
  t.boolean "status", default: true
end

期望的UI表格格式

表头固定为:检查日期(来自Appointment表)、检查项名称1(对应Result的findings)、检查项名称2(对应Result的findings)……
示例输出:

20-May-2021 100, 120, ....
20-June-2021 90, 120, ....

现有尝试代码

data = {}
result = []
appointments = Appointment.where("patient_id = ? and investigation_date IS NOT NULL", 
params[:p_id]).order("investigation_date desc").last(5)
appointment_id  = appointments.pluck(:id)
results_data    = Result.where(appointment_id: 
appointments.pluck(:id)).includes(:investigation)
appointments.each do |app|
 results_data.each do |data|
  result << data.findings
 end
 data[app.investigation_date.strftime("%d-%b-%Y")] = result
end

当前问题

现有代码无法得到正确格式的数据;参考@Lukas的建议调整后,仍存在数据与表头不匹配的问题(如"okay"对应表头的"E","90"对应表头的"M"),请求排查错误并提供解决方案。


问题排查与解决方案

现有代码的核心问题

  1. 循环逻辑错误:遍历每个appointment时,把所有results_data里的结果都塞进同一个数组,没有筛选当前appointment对应的结果
  2. 变量命名冲突:循环内的data变量和外层存储最终结果的data哈希重名,导致逻辑混乱
  3. 未按表头顺序匹配数据:没有固定Investigation的顺序,导致每个日期对应的检查结果和表头的检查项无法一一对应

修正后的代码实现

# 1. 先获取所有需要展示的检查项(作为表头,固定顺序,可按需过滤,比如只取启用状态的)
investigations = Investigation.where(status: true).order(:name).to_a
# 提取表头名称,用于UI展示
headers = ["检查日期"] + investigations.pluck(:name)

# 2. 获取目标患者的最近5次有效检查预约,预加载关联数据避免N+1查询
appointments = Appointment
  .where(patient_id: params[:p_id], investigation_date: !nil)
  .order(investigation_date: :desc)
  .last(5)
  .includes(results: :investigation)

# 3. 整理每个预约的检查结果,严格按表头顺序匹配
formatted_data = {}
appointments.each do |app|
  # 将当前预约的结果转成investigation_id => findings的哈希,快速查找
  app_results = app.results.index_by(&:investigation_id)
  # 按表头检查项顺序提取结果,无结果则留空或显示N/A
  findings = investigations.map do |investigation|
    app_results[investigation.id]&.findings || ""
  end
  # 存储日期对应的结果数组
  formatted_data[app.investigation_date.strftime("%d-%b-%Y")] = findings
end

代码说明

  • 先固定Investigation的排序规则,确保表头与每行结果的位置完全对应
  • 使用includes预加载关联数据,优化查询性能
  • 用index_by将当前预约的结果转为哈希,通过investigation_id快速匹配对应的检查项结果
  • 遍历预约时仅处理当前预约的结果,避免数据交叉混乱

内容的提问来源于stack exchange,提问作者Vibhoo Mishra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:24:24