我的rails应用程序中有一个Users类。我需要两种类型的用户,1)玩家,2)经理。用户将使用Devise登录并具有相同的基本用户字段。我将有一个联盟模型。对此进行建模的最佳方法是什么? STI似乎不太正确,但不确定Polymorphic是否有效,因为如果两者都管理器<用户&&播放器<用户。管理者唯一真正的角色是管理员角色,例如在联赛中添加/删除球员,设置赛程等。
class League < ActiveRecord::Base
has_one :manager
has_many :players
end
class Match < ActiveRecord::Base
has_and_belongs_to_many :players
belongs_to :league
end
class User < ActiveRecord::Base
has_and_belongs_to_many :matches
has_and_belongs_to_many :leagues
end
class Player < User
has_and_belongs_to_many :leagues
has_and_belongs_to_many :matches
end
class Manager < User
has_many :leagues
end
非常感谢任何有关设置此方法的最佳方法的建议! 对玩家使用STI ActiveRecord正在寻找连接的Player表,但它不存在。
答案 0 :(得分:3)
STI可以为此工作,但由于用户类型之间的差异基本上是一个表示用户是管理员的标志,因此您只需要用户检查是否允许某些操作。角色可以是独占的也可以是包含的(这样用户既可以是玩家也可以是经理),但是一旦设置完成,您就可以围绕用户拥有的功能塑造界面:
<% if @user.has_role?('manager') %>
<%= render 'manager_fields' # or manager_page, etc. %>
<% end %>
如何在控制器中处理这个问题取决于你如何通过Pundit,CanCanCan等宝石实现角色,或者通过对自己编写的内容进行明确检查。 gems将为您提供辅助方法,以减少视图中涉及的键入量,并在后端使用更具声明性的语法。
答案 1 :(得分:1)
STI消除了每个类的单独表的需要,因为大多数(或理想所有)属性在两个模型之间共享。
在这种情况下,我们在名为type
的用户表中添加一个新列,该列将指示将对此记录进行解析的类,因此Player
或Manager
至于模型
class Player < User
和
class Manager < User
对于权限,您可以检查用户实例的类型是Player
还是Manager
当然,如果你不想做,你不需要做STI,而是你要创建两个表players
和managers
,而你&#39;我需要使用User
模型加入它们,这将是棘手的,因为并非所有用户都有管理员而且并非所有用户都有玩家,因此除非您创建多态关系,否则其中一个或总是返回nil,... ,但是你需要检查对象的类型,.. idk
我认为STI是目前最好的解决方案