通过 Rails 5 中的另一个模型继承关联
Posted
技术标签:
【中文标题】通过 Rails 5 中的另一个模型继承关联【英文标题】:Inheriting an association via another model in Rails 5 【发布时间】:2019-06-27 14:17:03 【问题描述】:我正在进行一个非常标准的用户/角色设置(用户 HABTM 角色,角色 HABTM 用户)。我正在使用 CanCanCan 进行授权,您所拥有的角色定义了您可以围绕应用程序执行的操作。这部分一切正常,但现在我希望能够让用户继承角色,作为订阅不同成员资格的一部分。
以下是相关型号:
class User < ApplicationRecord
has_and_belongs_to_many :roles
has_one :membership_subscription
has_one :membership, through: :membership_subscription
end
class Role < ApplicationRecord
has_and_belongs_to_many :users
end
class MembershipSubscription < ApplicationRecord
belongs_to :user
belongs_to :membership
end
class Membership < ApplicationRecord
has_many :membership_subscriptions
has_many :users, through: :membership_subscriptions
end
我在想我也许可以只添加一个has_many: roles
关联到会员资格,然后说用户has_many
角色通过他们订阅会员资格,以及当前允许角色的HABTM 关联直接分配。
通过这种方式,您可以像现在一样直接将角色附加到用户(因为某些角色是附加的,与会员订阅/类型完全无关),但用户也会自动继承角色(并再次失去它们)作为他们的会员来来去去。
这有意义吗?我想另一种选择是在模型中使用回调来处理创建/删除角色关联,但它看起来并不优雅。
非常感谢任何建议!
【问题讨论】:
【参考方案1】:好的,我认为这是一个有效的答案:
首先,更新模型,以便在成员资格和角色之间建立关联:
class Role < ApplicationRecord
has_and_belongs_to_many :users
has_and_belongs_to_many :memberships
end
class Membership < ApplicationRecord
has_many :membership_subscriptions
has_many :users, through: :membership_subscriptions
has_and_belongs_to_many :roles
end
接下来,在用户模型中创建一个可用于检索直接分配的角色和继承的角色的方法:
def combined_roles
if self.membership == nil
self.roles
else
self.roles + self.membership.roles
end
end
然后在需要检查角色的任何地方,调用该方法而不是通常的user.roles
不确定这是否是一种幼稚的做事方式,但似乎可以正常工作。如果有更好的方法,仍然欢迎评论
编辑:
这允许用户多次拥有相同的角色 - 它可以直接分配或继承。修改 combine_roles 方法,使其去除重复项:
def combined_roles
if self.membership == nil
self.roles
else
(self.roles + self.membership.roles).uniq
end
end
【讨论】:
最后一件事要注意 - 通过运行self.roles + self.membership.roles
,您可以将 ActiveRecord 集合转换为数组。所以像.where
这样的方法不再起作用。例如,我必须更新我的 has_role
方法以使用 self.combined_roles.any? |h| h[:name] == role_name
而不是以前的 self.roles.where(:name => role_name).present?
您可以获取roles_ids 和membership.roles_ids,合并这些数组,然后执行Role.where(id: combined_roles_ids)
以使用activerecord 的查询而不是数组。以上是关于通过 Rails 5 中的另一个模型继承关联的主要内容,如果未能解决你的问题,请参考以下文章
带有has_many的模型中的属性总和:通过关联在Rails 5中不起作用
如何在has_many中获取模型的属性:通过Rails 5中的关联