Rails模型:对于众多角色,具有其他子角色的多个用户模型设计正确吗?

时间:2013-01-18 09:56:34

标签: ruby-on-rails database-design model role

我正在编写我的第一个Ruby On Rails应用程序 - 一个门控住宅社区的网站。

社区区域包含空地块,在一个建筑地块中有一个或多个房屋。地块只有一个拥有者,但地块中的多个房屋可以各有不同的所有者。有选举产生的不同角色的办公人员(在居民协会中)和物业管理人员等。最终会有用户组(仅限业主或仅租户或混合等)。

所有者和租户往往差别很大,因此我将它们作为单独的类别保留。同样,他们的家庭成员也有所不同 - OwnerFamilyMember和TenantFamilyMember课程。

我的第一个设计是拥有一个用户,一个角色和一个分配模型 - 角色变得太多了。因此我将用户模型拆分为上述(我不想使用STI或多态关联,我想先把它弄好)。

模型类:

# All classes below inherit from ActiveRecord::Base, removed other attributes for compactness

class Owner
    has_many :plots    
    has_many :houses   
    has_many :owner_family_members    
end

class Tenant
    belongs_to :house    # declare house_id in table
    has_many :tenant_family_members
end

class Staff ...

class Plot
    belongs_to :owner    # declare owner_id in table
end

class House
    belongs_to :owner    # declare owner_id in table
end

class OwnerFamilyMember
    belongs_to :owner    #  declare owner_id in table
end
class TenantFamilyMember
    belongs_to :tenant    #  declare tenant_id in table
end
  • 租户或业主居住在房屋内。
  • 家庭成员或租户将参与社区活动 但他们肯定依赖主要所有者或租户 特权行动

据我所知,通过这种设计,不同的用户模型具有隐含的角色,并且如果需要可以有其他子角色 - 所有者可以是居民协会的财务主管,租户可以领导水资源保护小组等。我期望进一步发展的角色数量,因此我认为保留多个用户模型会更好。

我是否在正确的轨道上?我在这个食谱中混淆了错误的东西吗?热衷于听取任何反馈,概念或具体实施,以帮助我更好地理解这一点。

我理解数据库概念,OO编程,但我是生产级数据库设计或RoR应用程序的新手。感谢阅读这篇长篇文章。 - Jayawanth

1 个答案:

答案 0 :(得分:0)

欢迎来到Rails社区!你会喜欢它。

首先,您不需要回避STI或多态关联,它们是Rails世界中非常有价值的工具。您的用户/角色/分配(联接表)策略似乎合理,以处理良好的规范化身份验证和基于角色的授权方法。我会保持用户模型与应用程序的其他逻辑完全分离,并使用Ryan Bates的CanCan库进行授权,并通过Plataforma的Devise库进行身份验证。

现在你有一个很好的身份验证/授权设置,它不依赖于很多不同的User / Admin / GuyWhoAuthenticates模型,而且应用程序更加简单。例如:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    ...
    if user.has_role? 'plot_owner'
      can :manage, Plot, user_id: user.id
    end
    ...
  end
end

class User < ActiveRecord::Base

  has_many :assignments
  has_many :roles, through: :assignments

  ...

  def has_role? role
    roles.where(label: role)
  end    

  ...

end

关于其他型号,一个好的经验法则是:它们共享多少逻辑?如果它们具有相同的属性,共享大量的应用程序逻辑并且在概念上相似(比如,作为一个家庭成员),那么我会选择STI /多态关联。如果没有,您可以将通用逻辑提取到一个单独的模块中,并将其包含在两个模型中。

由于您是Rails世界的新手,我还强烈建议您查看RailscastsPeepcode两个非常棒的截屏网站,这些网站可以让您立即制作像老板一样的Rails应用程序: d

干杯!