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
相关产品推荐
相关产品推荐

