假设我有一个名为Staff的模型。 staff对象附加到用户并且具有"标题"。现在,这个头衔可以是经理,医生,工程师,护士。哪种更好的做法?
声明一个常量并在Staff模型本身上有一个title属性
ROLES = ["manager", "doctor", "engineer", "nurse"]
或创建名为Role
的模型并将其设置为与Staff
模型的关系?此模型仅会有一个名为title
的属性。
我非常清楚这两种方法都有效,但我只想知道你们这些人。关于这一前进的观点/想法。
谢谢!
答案 0 :(得分:9)
如果您的角色系统如此简单 - 则无需使用一个字段创建另一个模型。
要实现该功能,我建议您查看rails ActiveRecord#enum
:http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html
答案 1 :(得分:3)
这完全取决于用例。如果您可以预见您应用程序中的用户将只有一个角色 - 那么请使用Sergii建议的枚举。它将是最简单,最高效的选择。
这还取决于您是否确实需要一个角色系统进行授权,或者您只是检查用户无论他们喜欢什么都不能自我标题。
如果您需要一个灵活的系统,用户可以拥有多个角色而不是您想要使用数据库表。
另一个问题是如何创建角色,它是否足够好以至于它是开发人员关注的问题?是否需要能够从GUI创建角色定义?
此示例显示了一个常见设置,其中包含用于角色定义的表和包含分配给用户的角色的连接表。
class User < ActiveRecord::Base
has_many :user_roles
has_many :roles, through: :user_roles
def has_role?(name, resource = nil)
scope = user_roles.joins(:role).where(
role: { name: name }
)
scope = scope.where(resource: resource) if resource
scope.any?
end
end
# join table with roles assigned to users
class UserRole < ActiveRecord::Base
belongs_to :user
belongs_to :role
belongs_to :resource, polymorphic: :true
end
# Role definitions
class Role < ActiveRecord::Base
has_many :user_roles
has_many :users, through: :roles
end
答案 2 :(得分:2)
听起来你只想 select * from table_name pivot(sum(name) for role
上的title
属性。
如果您想确保该标题是“允许的”标题之一。值,您可以在模型级别验证包含:
Staff
答案 3 :(得分:1)
始终从小处着手,让测试变为绿色,然后在需要时进行重构。
如果您只想为人们定义一个角色,那就像您想象的那样简单:
Call
到title
模型表Staff
模型中的新常量TITLES
Staff
模型中的新验证,如@petr-gazarov 如果需要新模型,请确保,您将别无选择,只能进行重构。只要你有选择,答案总是最简单的。
很快,您可能会开始问自己,您希望如何处理这种角色差异 - 剧透,你可能想了解更多关于授权的信息(例如“可以做什么”,与认证有关) “是谁”。) 因此,我将一石二鸟,并在role-based authorization上为您提供一个很好的指南,从一个非常简单实用的宝石中定义基于角色的授权:cancancan。