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

Ruby on Rails复杂左连接查询示例请求(三表关联场景)

没问题,我来帮你搞定Rails里的左连接查询需求!你要的是获取所有用户,包括那些没有关联合同类型的用户(不管是没有合同,还是合同的类型为空),用left_joins(Rails 5+引入的方法,对应SQL的LEFT OUTER JOIN)就能轻松实现,下面给你几个实用的示例:

1. 获取所有用户及其关联的合同类型(含无类型的用户)

这个查询会返回所有用户,不管他们有没有WorkContract或者WorkContractType,关联数据不存在时会是nil:

# 用left_joins做左连接,includes预加载关联避免N+1查询
users = User.left_joins(work_contracts: :work_contract_type)
            .includes(work_contracts: :work_contract_type)

# 遍历结果示例
users.each do |user|
  # 获取用户的所有合同类型(可能为空数组)
  contract_types = user.work_contract_types
  puts "用户ID: #{user.id}, 合同类型: #{contract_types.present? ? contract_types.pluck(:name).join(', ') : '无'}"
end

2. 筛选出没有任何合同类型的用户

如果你需要专门找出那些要么没有WorkContract,要么所有WorkContract都没有关联类型的用户,可以这样写:

users_with_no_contract_type = User.left_joins(work_contracts: :work_contract_type)
                                  .where(work_contract_types: { id: nil })
                                  .distinct
  • where(work_contract_types: { id: nil }):匹配那些WorkContractType记录不存在的情况(包括用户没有WorkContract的场景)
  • distinct:避免同一个用户因为多条无类型合同被重复返回

3. 获取每个用户的最新合同类型(含无类型的用户)

因为你的User模型里已经给work_contracts加了order 'start_on DESC'的默认排序,要获取每个用户最新的合同类型,可以结合子查询实现:

# 先查询每个用户的最新合同(利用DISTINCT ON,PostgreSQL适用)
latest_work_contracts = WorkContract.select('DISTINCT ON (user_id) *')
                                    .order('user_id, start_on DESC')

# 左连接到用户和合同类型
users = User.left_joins("LEFT JOIN (#{latest_work_contracts.to_sql}) latest_wc ON users.id = latest_wc.user_id")
            .left_joins('LEFT JOIN work_contract_types ON latest_wc.work_contract_type_id = work_contract_types.id')
            .select('users.*, work_contract_types.name AS latest_contract_type')

# 访问示例
users.each do |user|
  puts "用户ID: #{user.id}, 最新合同类型: #{user.latest_contract_type || '无'}"
end

原理说明

left_joins和普通的joins最大的区别是:

  • joins默认是内连接(INNER JOIN),会自动过滤掉没有关联记录的用户
  • left_joins是左外连接(LEFT OUTER JOIN),会保留左表(User)的所有记录,右表(WorkContract、WorkContractType)没有匹配时,对应字段会是NULL,这正是你需要的“包含合同类型为nil的用户”的核心逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:28:24