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

如何在Rails中基于关联Action的最早时间去重排序查询MyModel?

解决方案:数据库层面实现去重并按关联最早Action时间排序

你的需求完全可以在数据库层面完成,不需要在Rails层面做额外处理。当前scope返回重复MyModel的原因是group子句同时包含了my_models.id和actions.time,这会让每个不同的actions.time都生成独立分组,导致同一个MyModel对应多条记录。

修正后的Scope写法

你可以通过分组仅按my_models.id聚合,同时用MIN(actions.time)获取每个MyModel关联的最早Action时间,再基于这个值排序:

scope :my_scope, lambda {
  joins(:actions)
    .where.not(actions: { status: :finished })
    .select('my_models.*, MIN(actions.time) as earliest_action_time')
    .group('my_models.id')
    .order('earliest_action_time ASC')
}

说明

  • select语句中新增MIN(actions.time) as earliest_action_time:计算每个MyModel关联的未完成Action的最早时间,并起别名方便排序
  • group('my_models.id'):仅按MyModel的ID分组,确保每个MyModel只返回一条记录
  • order('earliest_action_time ASC'):基于计算出的最早时间升序排序(如果要降序改成DESC即可)

如果你的Rails版本支持,也可以用更具可读性的Arel写法避免硬写SQL字符串:

scope :my_scope, lambda {
  joins(:actions)
    .where.not(actions: { status: :finished })
    .select(MyModel.arel_table[Arel.star], Action.arel_table[:time].minimum.as('earliest_action_time'))
    .group(MyModel.arel_table[:id])
    .order(Arel.sql('earliest_action_time ASC'))
}

这样就能在数据库层面完成去重和排序,返回的结果是唯一的MyModel记录,且按关联的最早未完成Action时间排序。

内容的提问来源于stack exchange,提问作者Petros Kalafatidis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:05:37