Rails 4中如何在Scope内获取Disabling数据的最后一行?
Rails 4 中在模型 Scope 中获取关联数据最后一行并判断状态
要实现需求,关键是先过滤出每个 AbcRoot 对应的最后一条 AbcRootDisabling 记录,再基于这条记录判断是否符合「无禁用记录」或「最后一条禁用记录已启用」的条件。具体实现如下:
修改关联逻辑,获取最新禁用记录
替换原有的 including_abc_disablings 方法,通过子查询筛选出每个 abc_root_id 对应的最后一条禁用记录(这里假设 AbcRootDisabling 的 id 是自增主键,用 MAX(id) 确保取到最新记录):
def self.including_latest_abc_disablings # 子查询:分组获取每个 abc_root_id 对应的最新禁用记录 ID latest_disabling_subquery = AbcRootDisabling.select('abc_root_id, MAX(id) AS latest_id') .group('abc_root_id') .to_sql joins('JOIN abc_roots_abcs as crc ON crc.abc_id = abcs.id') # 左连接子查询,关联到每个 abc_root 的最新禁用记录 ID .joins("LEFT OUTER JOIN (#{latest_disabling_subquery}) AS latest_disablings ON crc.abc_root_id = latest_disablings.abc_root_id") # 再连接到具体的禁用记录,拿到最后一条的完整数据 .joins('LEFT OUTER JOIN abc_root_disablings as disablings ON latest_disablings.latest_id = disablings.id') end private_class_method :including_latest_abc_disablings
更新 not_disabled Scope 的判断条件
修改 not_disabled 作用域,加入「无禁用记录」或「最后一条禁用记录的 enabled_at 不为空」的判断:
scope :not_disabled, -> { including_latest_abc_disablings.where('disablings.id IS NULL OR disablings.enabled_at IS NOT NULL') }
逻辑说明
- 子查询筛选最新记录:通过分组取每个
abc_root_id的最大id,确保只关联到该AbcRoot的最后一条禁用记录,避免原逻辑中关联所有记录导致的判断错误。 - 左连接保证无记录场景:使用
LEFT OUTER JOIN确保即使某个AbcRoot没有禁用记录,对应的Abc也会被保留。 - 双条件判断:
disablings.id IS NULL对应无禁用记录的情况,disablings.enabled_at IS NOT NULL对应最后一条禁用记录已启用的情况,两者满足其一即符合「未禁用」要求。
内容的提问来源于stack exchange,提问作者Shruthi R
相关产品推荐
相关产品推荐

