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

Rails中如何通过最大role_version获取用户关联的角色记录?

解决方法

针对你的需求——获取指定用户关联的、每个角色对应最大role_version的职位描述所对应的角色,这里提供几种实用的实现方式:

方法一:直接通过数据库查询筛选

先通过子查询找出该用户每个role_id对应的最大role_version,再关联获取对应的职位描述和角色:

user_id = 1

# 子查询:获取当前用户每个角色的最大版本号
max_version_subquery = JobDescription.where(user_id: user_id)
                                     .group(:role_id)
                                     .select("role_id, MAX(role_version) AS max_version")

# 关联查询得到目标角色
target_roles = Role.joins(job_descriptions: :user)
                   .where(user_id: user_id)
                   .where(
                     job_descriptions: {
                       role_id: max_version_subquery.select(:role_id),
                       role_version: max_version_subquery.select(:max_version)
                     }
                   )
                   .distinct

方法二:在User模型中新增关联(推荐)

通过扩展User模型的关联,封装逻辑,方便复用:

class User < ApplicationRecord
  has_many :job_descriptions
  has_many :roles, through: :job_descriptions

  # 关联:获取当前用户每个角色的最新版本职位描述
  has_many :latest_job_descriptions, ->(user) {
    subquery = JobDescription.where(user_id: user.id)
                             .group(:role_id)
                             .select("role_id, MAX(role_version) AS max_version")
    where("(role_id, role_version) IN (#{subquery.to_sql})")
  }, class_name: "JobDescription"

  # 通过最新职位描述关联角色
  has_many :latest_roles, through: :latest_job_descriptions, source: :role
end

使用时直接调用关联即可:

user = User.find(1)
user.latest_roles # 返回符合要求的角色集合

方法三:使用窗口函数(适用于支持窗口函数的数据库,如PostgreSQL)

利用窗口函数按角色分组、版本倒序排序,取每组第一条:

user_id = 1

# 构造筛选最新版本职位描述的子查询
latest_jobs_subquery = JobDescription.select("*, ROW_NUMBER() OVER (PARTITION BY role_id ORDER BY role_version DESC) AS rn")
                                     .where(user_id: user_id)
                                     .having("rn = 1")
                                     .to_sql

# 关联得到目标角色
target_roles = Role.joins("JOIN (#{latest_jobs_subquery}) jd ON roles.id = jd.role_id")
                   .distinct

以上三种方法都能实现需求,其中方法二更符合Rails的开发习惯,便于后续复用和维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:39:51