Rails STI 与多态性与两者都不是

Rails STI vs Polymorphic vs Neither

我的 rails 应用程序中有一个用户 class。我需要两种类型的用户,1) 玩家,2) 经理。用户都将使用 Devise 登录并具有相同的基本用户字段。我会有一个联盟模型。对此建模的最佳方法是什么? STI 似乎不太正确,但不确定多态是否有效,因为如果两者都是 Manager < User && Player < User。经理将拥有的唯一真正角色是管理角色,例如 adding/removing 来自联盟的球员,设置时间表等。

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 正在寻找播放器 table 进行加入,但它不存在。

STI 消除了每个 class 的单独 table 的需要,因为大多数(或理想情况下所有)属性在两个模型之间共享。
在这种情况下,我们将在用户 table 中添加一个名为 type 的新列,这将指示该记录将被解析到的 class,因此 PlayerManager
至于型号

class Player < User

class Manager < User

至于权限,您可以检查用户实例的类型是 Player 还是 Manager

当然,如果您不想,则不需要进行 STI,相反,您将创建两个 tables playersmanagers,然后您将需要用 User 模型加入他们,这会很棘手,因为不是所有用户都有经理,也不是所有用户都有玩家,所以一个或另一个总是 return nil,..除非你创建一个多态关系,但是你需要检查对象的类型,.. idk

我认为 STI 是目前最好的解决方案

STI 可以解决这个问题,但由于用户类型之间的区别基本上是一个表明用户是管理员的标志,您只需要对用户进行一些检查,以检查他们是否被允许执行某些操作。角色可以是排他性的或包容性的(这样用户既可以是玩家也可以是经理),但是一旦设置好,您就可以围绕用户拥有的能力来塑造界面:

<% if @user.has_role?('manager') %>
  <%= render 'manager_fields' # or manager_page, etc. %>
<% end %>

你如何在控制器中处理这个取决于你如何实现角色,要么通过 Pundit、CanCanCan 等 gem,要么通过显式检查你自己编写的东西。这些 Gems 将为您提供辅助方法,以减少视图中涉及的输入量,并在后端提供更具声明性的语法。