Rails 5 中为不同组分配用户角色的最佳方法?

Best approach for assigning user roles for different groups in Rails 5?

以下是没有角色的基本模型:

群模型

    class Group < ApplicationRecord
      has_many :memberships
      has_many :users, through :memberships
    end

用户模型

    class User < ApplicationRecord
      has_many :memberships
      has_many :groups, through :memberships
    end

会员模式

    class Membership < ApplicationRecord
      belongs_to :group
      belongs_to :user
    end

每个组应该有 1 个(并且只有一个)owner、多个 admins(由所有者分配),其余 general 个成员。此外,所有权角色需要可转让。我的选择,如我所见:

  1. 在成员资格 table 上创建单个属性 role 并为其分配字符串值 "owner"、"manager" 或 "general". [差]

  2. 为成员 table 上的 "owner"、"manager" 和 "general" 创建多个布尔值。 [差]

  3. 创建一个 Role model/table 具有 1 列 ("name") 和 3 行 ("owner", "manager", "general") 然后像这样更新我的模型:

榜样

    class Role < ApplicationRecord
      has_many :memberships
      has_many :users, through :memberships
      has_many :groups, through :memberships
    end

群模型

    class Group < ApplicationRecord
      has_many :memberships
      has_many :users, through :memberships
      has_many :roles, through :memberships
    end

用户模型

    class User < ApplicationRecord
      has_many :memberships
      has_many :groups, through :memberships
      has_many :roles, through :memberships
    end

会员模式

    class Membership < ApplicationRecord
      belongs_to :group
      belongs_to :user
      belongs_to :role
    end
  1. 直接在组模型上为各种角色创建单独的数组。这看起来真的很愚蠢,因为更新一个角色需要压入和拼接多个数组,我将不得不连接多个数组来呈现一个简单的成员列表。

群模型

    class Group < ApplicationRecord
      has_many :general_memberships, class_name: 'Membership'
      has_many :admin_memberships, class_name: 'Membership'
      has_one :owner_membership, class_name: 'Membership'

      has_many :users, through :memberships
    end

用户模型

    class User < ApplicationRecord
      has_many :general_memberships, class_name: 'Membership'
      has_many :admin_memberships, class_name: 'Membership'
      has_many :owner_memberships, class_name: 'Membership'

      has_many :groups, through :memberships
    end

会员模式

    class Membership < ApplicationRecord
      belongs_to :group
      belongs_to :user
    end

我知道那里有 gems,比如 CanCanCan(Rails 5 兼容?)和 Groupify,但我想先了解我的所有选择。我认为选项 #3 可能是我最好的选择,至少在不使用 gem 的情况下是这样。想知道社区认为我的场景的最佳实践是什么。

更新

我最终采用了以下解决方案,并且在生产应用程序中对它非常满意。由于一个组只能有一个所有者,因此它为该角色使用 belongs_to 关系。

对于会员模型,我利用了活动记录枚举。由于枚举数组仅包含两个值,实际上向成员模型添加一个 "manager" 布尔值会更有效。 True 表示经理,false 表示一般。但我选择了枚举方法,因为我预计在不久的将来需要更多角色,使用枚举将非常容易添加。

群模型

    class Group < ApplicationRecord
      belongs_to :owner, class_name: 'User'
      has_many :memberships
      has_many :users, through :memberships
    end

用户模型

    class User < ApplicationRecord
      has_many :owned_groups, class_name: 'Group', :foreign_key => 'owner_id'
      has_many :memberships
      has_many :groups, through :memberships
    end

会员模式

    class Membership < ApplicationRecord
      belongs_to :group
      belongs_to :user

      enum role: [:general, :manager]
    end