Ruby中通过has_many关联获取miq_user_roles表user值的方法
实现方法
你不需要额外新增has_many关联,直接用MiqUserRole模型已经定义好的关联链就能实现查询,核心是打通角色到用户的关联路径,同时匹配settings字段里存储的:user限制规则。
- 关联链路说明
现有模型已经预置了两层has_many关联:MiqUserRole直接关联:entitlementsMiqUserRole通过entitlements间接关联:miq_groups
这套代码所属的ManageIQ框架中,MiqGroup模型默认自带has_many :users关联,整条链路可以直接从角色表关联到用户表,不需要额外定义关联。
- 批量查询写法(推荐,性能好)
直接在查询中联表,同时匹配settings中vms: :user的规则,就能直接拿到符合条件的用户集合,后续直接在where条件中做值比对即可:# 联表查询所有归属「VM仅用户自有」角色的用户 matched_users = User.joins(miq_groups: { entitlements: :miq_user_role }) .where( miq_user_roles: { # 匹配settings里restrictions.vms值为user的角色,对应你贴的id=34的Catalog_Viewers角色 "settings -> 'restrictions' ->> 'vms'" => "user" } ) # 直接用结果集做where比对,比如判断指定用户是否符合条件 User.where(id: matched_users.select(:id)).where(你的其他用户字段比对条件) - 兼容写法(适配不支持JSON操作的老版本数据库)
如果你的settings字段是纯text类型存储序列化YAML、不支持JSON路径查询,可以用模型自带的判断方法先筛出符合条件的角色ID,再走关联查询:# 模型自带的limited_self_service?方法就是专门判断vms限制是否为:user的 valid_role_ids = MiqUserRole.all.select(&:limited_self_service?).map(&:id) matched_users = User.joins(miq_groups: :entitlements) .where(entitlements: { miq_user_role_id: valid_role_ids })
注意:不要在循环中单独调用实例方法判断角色规则,批量查询场景下联表写法的性能远高于逐行加载序列化对象判断的写法,能避免N+1查询问题。
内容的提问来源于stack exchange,提问作者user630702
相关产品推荐
相关产品推荐

