如何在Rails中为User与Rule模型建立两种不同关联?
解决User与Rule的双重关联问题
你现在的问题是要同时支持“用户创建规则”和“规则分配给用户(多态)”这两种场景,核心是要把两种关联明确区分开,不能共用同一个关联名称,不然Rails会混淆。下面是具体的实现方案:
第一步:调整数据库迁移
首先需要给Rule表添加两个关键关联字段:一个记录规则的创建者(owner_id),另一个支持多态关联的字段组(rulable_type和rulable_id)。运行以下生成迁移的命令:
rails generate migration AddOwnerAndRulableToRules owner:references rulable:references{polymorphic}
然后执行迁移生效:
rails db:migrate
第二步:修改User模型
在User里分别定义两种关联:一种是作为规则创建者的关联,另一种是作为规则被分配对象的多态关联:
class User < ApplicationRecord # 关联该用户创建的所有规则(作为所有者) has_many :created_rules, class_name: 'Rule', foreign_key: 'owner_id', dependent: :destroy # 关联分配给该用户的所有规则(作为多态对象) has_many :assigned_rules, as: :rulable, class_name: 'Rule', dependent: :destroy end
第三步:修改Rule模型
Rule需要同时关联创建者和多态对象:
class Rule < ApplicationRecord # 关联规则的创建者(用户) belongs_to :owner, class_name: 'User' # 多态关联,支持将规则分配给User或其他模型 belongs_to :rulable, polymorphic: true end
第四步:使用示例
现在你可以轻松处理两种业务场景了:
- 创建规则:用户作为所有者创建规则
# 找到用户 user = User.find(1) # 创建该用户拥有的规则 user.created_rules.create(name: "禁止修改权限", description: "普通用户不能修改系统权限") - 分配规则给用户:把已有的规则分配给目标用户
# 找到要分配的规则 rule = Rule.find(1) # 找到目标用户 target_user = User.find(2) # 分配规则 rule.update(rulable: target_user) - 查询规则:
- 获取用户创建的所有规则:
user.created_rules - 获取分配给该用户的所有规则:
user.assigned_rules - 获取该用户所有相关的规则(创建的+分配的),可以在User模型里加一个快捷方法:
调用时直接用:def all_related_rules Rule.where(owner_id: id).or(Rule.where(rulable: self)) enduser.all_related_rules
- 获取用户创建的所有规则:
这样就能完美支持你需要的两种业务场景啦,而且扩展起来也方便——如果之后要把规则分配给其他模型(比如Group),只需要给对应的模型加上has_many :assigned_rules, as: :rulable, class_name: 'Rule'就可以了。
内容的提问来源于stack exchange,提问作者Kumar
相关产品推荐
相关产品推荐

