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

Rails中如何按状态条件从关联表获取对应任务的最后记录?

解决方案:基于任务最终状态筛选任务

这个需求的核心是要找出每个任务的最终状态(也就是优先级最高的状态,这里状态ID越大优先级越高:已完成(4) > 暂停(3) > 运行中(2) > 已启动(1)),然后筛选那些最终状态匹配目标值的任务。

思路拆解

每个任务可能有多条状态记录,我们需要先对每个任务的状态分组,找到它的最高优先级状态(用MAX(status_id)即可实现),再筛选出最高状态等于目标值的任务。

代码实现

1. 直接获取符合条件的task_id

如果只需要返回任务ID,可以直接通过TaskStatus模型查询:

# 搜索「运行中」(status_id=2)的task_id
running_task_ids = TaskStatus.group(:task_id).having('MAX(status_id) = ?', 2).pluck(:task_id)
# 返回结果: [2]

# 搜索「已完成」(status_id=4)的task_id
completed_task_ids = TaskStatus.group(:task_id).having('MAX(status_id) = ?', 4).pluck(:task_id)
# 返回结果: [1]

2. 获取完整的Task对象

如果需要返回对应的Task实例,需要确保模型之间的关联正确,再通过关联查询实现:

首先确认模型关联:

# app/models/task.rb
class Task < ApplicationRecord
  has_many :task_statuses
end

# app/models/task_status.rb
class TaskStatus < ApplicationRecord
  belongs_to :task
end

然后执行查询:

# 获取所有「运行中」的Task对象
running_tasks = Task.joins(:task_statuses)
                    .group('tasks.id')
                    .having('MAX(task_statuses.status_id) = ?', 2)

# 获取所有「已完成」的Task对象
completed_tasks = Task.joins(:task_statuses)
                      .group('tasks.id')
                      .having('MAX(task_statuses.status_id) = ?', 4)

3. 子查询方式(更清晰的逻辑)

如果觉得分组查询不够直观,也可以用子查询先找出每个任务的最终状态,再关联筛选:

# 子查询:获取每个task_id对应的最高状态
final_status_subquery = TaskStatus.select('task_id, MAX(status_id) as max_status').group(:task_id)

# 筛选「运行中」的任务
running_tasks = Task.joins("INNER JOIN (#{final_status_subquery.to_sql}) sub ON tasks.id = sub.task_id")
                    .where('sub.max_status = ?', 2)

# 筛选「已完成」的任务
completed_tasks = Task.joins("INNER JOIN (#{final_status_subquery.to_sql}) sub ON tasks.id = sub.task_id")
                      .where('sub.max_status = ?', 4)

为什么这样可行?

因为你的数据中:

  • Task 1的状态记录包含1、2、3、4,最高状态是4(已完成),所以只会在搜索「已完成」时被匹配
  • Task 2的状态记录包含1、2,最高状态是2(运行中),所以只会在搜索「运行中」时被匹配

完全符合你的需求~

内容的提问来源于stack exchange,提问作者Krunal Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:39:10