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

Rails中如何编写基于has_one关联属性筛选的模型scope

解决方案

核心实现

你可以直接通过分组聚合的方式实现该scope,逻辑和你定义的next_appointment关联的规则完全对齐,代码如下:

scope :by_range_next_appointment_date, lambda { |from, to|
  joins(:appointments)
    .where("appointments.appointment_date >= NOW()")
    .group("patients.id")
    .having("MIN(appointments.appointment_date) BETWEEN ? AND ?", from, to)
}

逻辑说明

  • 先关联appointments表,过滤掉所有已过期的预约,和next_appointment的前置筛选规则保持一致
  • 按患者ID分组,每个分组对应单个患者的所有未来预约
  • 用MIN()聚合函数取出每个患者的最早未来预约日期,也就是next_appointment对应的日期
  • 最后通过having子句筛选出最早预约日期落在from和to区间内的患者,完全符合需求

你给出的测试用例可以完美适配:

Bruce Banner的最早未来预约为2021年11月2日,落在11月1日-11月7日区间内,会被筛选出来
Peter Parker的最早未来预约为2021年10月27日,不在目标区间内,会被排除

健壮性优化

如果存在from或to为空的场景,可以增加空值判断避免报错:

scope :by_range_next_appointment_date, lambda { |from, to|
  return all if from.blank? || to.blank?

  joins(:appointments)
    .where("appointments.appointment_date >= NOW()")
    .group("patients.id")
    .having("MIN(appointments.appointment_date) BETWEEN ? AND ?", from, to)
}

内容的提问来源于stack exchange,提问作者Code-Apprentice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:54:03