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

Rails中关联has_many时如何加载特定关联记录并筛选用户

背景

用户(User)与组织(Organisation)为多对多关系,UserOrganisation作为连接模型,存储特定用户在特定组织中的相关数据。
模型定义如下:

class Organisation < ApplicationRecord
  has_many :user_organisations, dependent: :destroy
  has_many :users, through: :user_organisations
end
class User < ApplicationRecord
  has_many :user_organisations, dependent: :destroy
  has_many :organisations, through: :user_organisations
end
class UserOrganisation < ApplicationRecord
  belongs_to :user
  belongs_to :organisation
end
问题需求

需要获取某一特定组织下的所有用户,排除super_user属性为true的用户,同时预加载对应的UserOrganisation连接记录。

目前使用的代码如下:

class User < ApplicationRecord
  scope :super_users, -> { where(super_user: true) }
end

@organisation.users.excluding(User.super_users)

希望能够直接引用对应UserOrganisation(即UserOrganisation.where(user_id: user.id, organisation_id: @organisation.id))中的字段值,询问是否有更合适的写法,还是必须使用@organisation.user_organisations.joins(:users).merge(User.not_super_users)这种方式?

解决方案

写法一:从用户维度查询并精准预加载连接记录

先给User模型补充非超级用户的Scope,再在查询时直接限定预加载的连接记录为当前组织:

class User < ApplicationRecord
  scope :super_users, -> { where(super_user: true) }
  scope :non_super_users, -> { where(super_user: false) }
end

# 查询组织下的非超级用户,同时只预加载当前组织对应的UserOrganisation记录
users = @organisation.users.non_super_users.includes(:user_organisations).where(user_organisations: { organisation_id: @organisation.id })

这种写法拿到的每个user对象,其user.user_organisations只会包含当前组织对应的那条连接记录,直接就能引用其中的字段。

写法二:从连接模型出发查询(更直接高效)

你提到的从user_organisations出发的写法其实非常合适,一次查询就能同时拿到连接模型和关联用户的数据,后续可以直接访问双方字段:

# 基于补充的non_super_users Scope查询
user_org_records = @organisation.user_organisations.joins(:user).merge(User.non_super_users).includes(:user)

# 访问连接模型字段
user_org_records.first.specific_field_in_user_organisation
# 访问关联用户信息
user_org_records.first.user

这种方式避免了多余的数据加载,代码简洁且性能更优。

原写法的问题

你原来的@organisation.users.excluding(User.super_users)是先加载组织下所有用户,再在内存中过滤超级用户,数据量大时会浪费性能;而且预加载user_organisations时会加载用户所有组织的连接记录,后续还要额外筛选当前组织的,完全没必要。

内容的提问来源于stack exchange,提问作者Phil-6

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:20:23