在Rails 5中通过另一个模型继承关联

时间:2019-02-03 18:16:52

标签: ruby-on-rails activerecord authorization associations roles

我正在进行一个非常标准的用户/角色设置(一个用户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 个答案:

答案 0 :(得分:0)

好的,我认为这是一个有效的答案:

首先,更新模型,以便在成员资格和角色之间建立关联:

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

不确定这是否是一种幼稚的处理方式,但似乎可以正常工作。如果有更好的方法,仍然欢迎发表评论

编辑:

这允许用户多次具有相同的角色-可以直接分配角色或继承角色。像这样修改combined_roles方法,以使其去除重复项:

def combined_roles
  if self.membership == nil
    self.roles
  else
    (self.roles + self.membership.roles).uniq
  end
end