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

如何合并两个ActiveRecord::Relation并返回Relation对象而非Array

问题根源

  • + 运算符会立即执行两个Relation的查询,将结果加载为内存数组,不再保留ActiveRecord::Relation类型
  • or 方法要求两个Relation的结构完全一致(包括select字段、关联join、分组排序等子句),你的两个Relation分别关联了不同表、选择了不同字段,因此触发兼容报错

解决方案

根据你的业务需求可以选择以下两种方案:

方案1:直接关联两张表(适用于需要同时获取两个关联表字段的场景)

不需要拆分两个Relation再合并,直接写一个同时左连两个关联的Relation即可,最终结果天然就是ActiveRecord::Relation类型:

companies = Company.select(
  "companies.company_code,
  event_contracts.company_name,
  event_plans.content"
).left_joins(:event_contracts, :event_plans)

如果你的两个原始Relation还有额外的过滤条件,可以直接在这个基础上链式调用where即可,也支持用or拼接同结构的过滤条件。

方案2:UNION合并结果集(适用于需要取两个Relation结果并集的场景)

如果你的两个Relation逻辑完全独立,确实需要合并两者的查询结果,可以先对齐两个Relation的select结构(字段数量、类型保持一致,缺省字段用NULL填充并起相同别名),再通过UNION拼接为子查询包装为Relation:

# 对齐两个Relation的select结构
relation_1_aligned = Company.select(
  "companies.company_code,
  event_contracts.company_name as val1,
  NULL as val2"
).left_joins(:event_contracts)

relation_2_aligned = Company.select(
  "companies.company_code,
  NULL as val1,
  event_plans.content as val2"
).left_joins(:event_plans)

# 拼接UNION SQL并包装为Relation
union_sql = "(#{relation_1_aligned.to_sql}) UNION (#{relation_2_aligned.to_sql})"
companies = Company.from("#{union_sql} as companies")

注意:如果不需要去重,可以把UNION替换为UNION ALL获得更高的查询性能。

最终得到的companies都是可链式调用的ActiveRecord::Relation类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:54:08