安排我的类rails mongoid

时间:2016-05-16 18:17:02

标签: ruby-on-rails associations mongoid

我有4种用户类型

-SuperAdmin
-Admin
-Manager
-Tenant

我目前有2个连接器类

-manager_approval
-reportapproval

租户创建并拥有Report类。

我需要确保Admin,SuperAdmin,Managers和Tenants可以访问Tenants.report的实例

目前我有以下设置,但我不确定这是否正确

class SuperAdmin
 include Mongoid::Document

 has_many :admins
 has_many :managers
 has_many :reports
end

class Admin
  belongs_to :super_admin
  has_many :manager_approvals, dependent: :destroy
  has_many :managers
  has_many :reportapprovals
  has_many :reports
end

class belongs_to :admin
  has_many :tenants
  has_many :reports
  has_many :reportapprovals, dependent: :destroy
  has_many :coupons
  has_many :manager_approvals, dependent: :destroy
end

class Tenant
 include Mongoid::Document

 has_one :report, dependent: :destroy
 has_one :tenant_record, dependent: :destroy, autosave: true
 has_many :reportapprovals, dependent: :destroy, autosave: true
 has_many :managers
end

class Reportapproval
  include Mongoid::Document

  belongs_to :tenant, inverse_of: :reportapprovals
  belongs_to :manager, inverse_of: :reportapprovals
  belongs_to :admins
  has_many :reports, dependent: :destroy
  belongs_to :manager_approvals
end

class ManagerApproval
 include Mongoid::Document

 belongs_to :admin, inverse_of: :managers, dependent: :destroy
 belongs_to :manager
 has_many :reportapprovals
 has_many :reports
end

class Report
 include Mongoid::Document

 belongs_to :tenant, dependent: :destroy
 has_and_belongs_to_many :reportapprovals
 has_and_belongs_to_many :managers, through: :reportapprovals
 has_many :admins, through: :managers
end

这对我来说不合适,并希望有人对其进行审核。最终,报告由租户创建,经理可以访问报告,管理员可以访问管理员可以访问的所有报告,SuperAdmin可以访问所有经理的所有报告。谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

单一集合继承

使用继承,以便将不同类型的用户填充到同一个集合中:

class User
  include Mongoid::Document
end

class Admin < User
end

class SuperAdmin < User
end

在SQL世界中,这就是单表继承。 MongoDB的无模式特性消除了STI的许多缺点,使其成为一个非常强大的工具。

这可以让您查询所有用户类型:

User.where(name: 'Bob') # returns any subtype

或特定类型的用户:

Admin.where(name: 'Bob') # returns only documents with the class Admin.

在处理您可能只知道用户ID但不知道类型的授权时,这一点尤为重要。

让我们滚动

虽然拥有User类和Admin类(等)并设置具有升级权限的复杂类树可能看起来是一个合理的想法,它很少适用于现实。并且有很多缺点:

  • 当用户晋升甚至降级时,您如何处理?
  • 如果用户属于多个类别会怎么样?

相反,考虑使用带有用户和角色的tried and true pattern,它允许很多可扩展性。例如,您可以将角色范围限定为特定资源或创建角色层次结构。

class User
  include Mongoid::Document
  embeds_many :roles

  def has_role?(role)
    self.roles.where(name: role).any?
  end

  def admin?
    has_role? :admin
  end

  def admin!
    self.roles.find_or_create_by!(name: :admin)
  end
end

class Role
  include Mongoid::Document
  embedded_in :user
  field :name, type: Symbol
end

请注意,由于在类上声明关系的方式而不是每个实例,基本用户类将包含所有关系:

class User
  include Mongoid::Document
  embeds_many :roles

  # ...
  has_many :reports
  has_many :report_approvals

  # ...
end

虽然它有可能在运行时将它添加到实例中,但它看起来很糟糕。