Rails中ServiceTemplate调用joins关联miq_user_roles报错
报错原因
ActiveRecord的joins方法使用关联名称做参数时,要求必须提前在模型中显式定义对应的关联关系。查看你贴出的ServiceTemplate模型代码,没有声明任何指向miq_user_roles表的关联,所以ORM找不到对应关联,直接抛出参数错误。
另外需要注意:从你提到的字段对应关系来看,你大概率混淆了ManageIQ项目的默认表结构——默认逻辑下service_templates.miq_group_id外键关联的是miq_groups(用户组表)的主键,miq_user_roles(用户角色表)的主键是关联在miq_groups表的miq_user_role_id字段上,并非直接和service_templates表关联。
修复方案
根据你实际的表结构选择对应方案:
方案1:确认miq_group_id直接关联miq_user_roles.id
在ServiceTemplate模型中补充缺失的关联声明即可,因为外键存在于当前模型对应的表中,使用belongs_to定义:
# 将这段代码添加到模型的关联定义区域 belongs_to :miq_user_role, class_name: 'MiqUserRole', foreign_key: :miq_group_id
注意关联名单数使用更符合Rails规范,添加后需要同步修改scope里的关联名为单数:
scope :public_service_templates, -> { joins(:miq_user_role).where(miq_user_roles: { settings: nil }) }
方案2:遵循ManageIQ默认表结构(绝大多数场景适用)
如果是默认结构,你需要通过miq_groups表做嵌套关联,不需要额外定义到miq_user_roles的直接关联,只需要先补全miq_group的关联,再修改scope为嵌套join即可:
- 先在模型中补充用户组关联:
belongs_to :miq_group
- 修改scope使用嵌套关联查询:
scope :public_service_templates, -> { joins(miq_group: :miq_user_role).where(miq_user_roles: { settings: nil }) }
临时方案(不推荐)
如果不想在模型中新增关联,也可以直接传入原生SQL片段实现join,但是可维护性差,后续表结构变更时容易漏改:
scope :public_service_templates, -> { joins("INNER JOIN miq_user_roles ON miq_user_roles.id = service_templates.miq_group_id").where(miq_user_roles: { settings: nil }) }
内容的提问来源于stack exchange,提问作者user630702
相关产品推荐
相关产品推荐

