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,因此 Player
或 Manager
至于型号
class Player < User
和
class Manager < User
至于权限,您可以检查用户实例的类型是 Player
还是 Manager
当然,如果您不想,则不需要进行 STI,相反,您将创建两个 tables players
和 managers
,然后您将需要用 User
模型加入他们,这会很棘手,因为不是所有用户都有经理,也不是所有用户都有玩家,所以一个或另一个总是 return nil,..除非你创建一个多态关系,但是你需要检查对象的类型,.. idk
我认为 STI 是目前最好的解决方案
STI 可以解决这个问题,但由于用户类型之间的区别基本上是一个表明用户是管理员的标志,您只需要对用户进行一些检查,以检查他们是否被允许执行某些操作。角色可以是排他性的或包容性的(这样用户既可以是玩家也可以是经理),但是一旦设置好,您就可以围绕用户拥有的能力来塑造界面:
<% if @user.has_role?('manager') %>
<%= render 'manager_fields' # or manager_page, etc. %>
<% end %>
你如何在控制器中处理这个取决于你如何实现角色,要么通过 Pundit、CanCanCan 等 gem,要么通过显式检查你自己编写的东西。这些 Gems 将为您提供辅助方法,以减少视图中涉及的输入量,并在后端提供更具声明性的语法。
我的 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,因此 Player
或 Manager
至于型号
class Player < User
和
class Manager < User
至于权限,您可以检查用户实例的类型是 Player
还是 Manager
当然,如果您不想,则不需要进行 STI,相反,您将创建两个 tables players
和 managers
,然后您将需要用 User
模型加入他们,这会很棘手,因为不是所有用户都有经理,也不是所有用户都有玩家,所以一个或另一个总是 return nil,..除非你创建一个多态关系,但是你需要检查对象的类型,.. idk
我认为 STI 是目前最好的解决方案
STI 可以解决这个问题,但由于用户类型之间的区别基本上是一个表明用户是管理员的标志,您只需要对用户进行一些检查,以检查他们是否被允许执行某些操作。角色可以是排他性的或包容性的(这样用户既可以是玩家也可以是经理),但是一旦设置好,您就可以围绕用户拥有的能力来塑造界面:
<% if @user.has_role?('manager') %>
<%= render 'manager_fields' # or manager_page, etc. %>
<% end %>
你如何在控制器中处理这个取决于你如何实现角色,要么通过 Pundit、CanCanCan 等 gem,要么通过显式检查你自己编写的东西。这些 Gems 将为您提供辅助方法,以减少视图中涉及的输入量,并在后端提供更具声明性的语法。