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

如何通过单条查询从SectionAdvice与Lecture表获取Activity数据?

可以通过单条查询实现需求

你可以直接从Activity模型出发,通过EXISTS子查询结合OR条件一次性筛选出符合要求的记录,同时避免重复数据。

步骤1:补充Activity模型的反向关联(可选但推荐)

先给Activity添加与SectionAdvice、Lecture的反向关联,让查询更符合Rails规范:

class Activity < ApplicationRecord
  belongs_to :area
  has_many :section_advices
  has_many :lectures
end

步骤2:单条查询实现方案

方式1:使用SQL字符串(直观易读)

# 假设contract_ids是你要传入的合同ID数组,participant_id是目标参与者ID
Activity.kept
  .where(
    "EXISTS (SELECT 1 FROM section_advices WHERE section_advices.activity_id = activities.id AND section_advices.contract_id IN (?) AND section_advices.kept = ?) 
     OR EXISTS (SELECT 1 FROM lectures WHERE lectures.activity_id = activities.id AND lectures.participant_id = ? AND lectures.kept = ?)",
    contract_ids, true, participant_id, true
  )
  .distinct

方式2:使用Arel(更安全,避免SQL注入风险)

如果不想直接写SQL字符串,可以用Rails的Arel构造查询:

section_advice_condition = SectionAdvice.kept
  .where(contract_id: contract_ids)
  .where(SectionAdvice.arel_table[:activity_id].eq(Activity.arel_table[:id]))
  .exists

lecture_condition = Lecture.kept
  .where(participant_id: participant_id)
  .where(Lecture.arel_table[:activity_id].eq(Activity.arel_table[:id]))
  .exists

Activity.kept.where(section_advice_condition.or(lecture_condition)).distinct

方案说明

  • EXISTS子查询:分别检查Activity是否关联符合条件的SectionAdvice或Lecture,比JOIN更高效(不会产生重复行)。
  • OR条件:满足任意一个关联条件的Activity都会被选中。
  • distinct:确保最终结果中没有重复的Activity记录(比如某个Activity同时关联符合条件的SectionAdvice和Lecture时)。
  • kept:所有关联表的查询都加上了这个scope,确保只查询未被软删除的记录。

对比原方案的优势

原方案是两次查询后在Ruby层面合并数据,不仅会产生额外的数据库请求,还可能出现重复数据需要手动去重;单条查询直接在数据库层面完成筛选和去重,性能更优,代码也更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:05:13