Rails 3:应该使用STI还是仅使用一列? 寻求建议

问题描述

| 我正在一个项目(Rails 3.0.3)中工作,我认为我可能需要使用STI,但是我不确定是否应该在表中添加额外的列并使用它。 在我的对象模型中,(对于游戏系统)我有玩家(属于代理商)和所有者(拥有代理商)。 玩家和所有者都由代理商(拥有用户帐户)拥有,因此代理商可以是许多代理商中的玩家和/或所有者。 我应该将代理命名为\'user \',哎呀。所以我有这个:
class Agency < ActiveRecord::Base
  has_many :players,:class_name => \"Player\",:foreign_key => \"agency_id\"
  has_many :agents,:through => :players,:source => :agent_id
  has_one :owner,:class_name => \"Owner\",:foreign_key => \"agency_id\"
end

class Player < ActiveRecord::Base
  belongs_to :agency,:class_name => \"Agency\",:foreign_key => \"agency_id\"
  belongs_to :agent,:class_name => \"Agent\",:foreign_key => \"agent_id\"
end

class Owner < ActiveRecord::Base
  belongs_to :agency,:foreign_key => \"agent_id\"
end
玩家和所有者都具有完全相同的属性,两者之间的唯一区别是所有者与代理商之间的关系与玩家之间的关系不同(所有者拥有代理商,代理商只有一个所有者,但拥有许多参与者)。 此外,所有者还拥有特殊权利,例如可以在代理机构中调整设置。 从纯粹的OOP角度来看,Owner是Player的子类(或者Owner和Player都是一些未定义类的子类,例如Participant等),但是考虑到持久性时,拥有单独的Player和owner表似乎是糟糕的数据库设计。 我的第一个想法是重构和使用STI,或者使Owner成为Player的子类,或者引入一个新的基类,然后再对Owner和Player进行子类化。 我的另一种想法是,我可以在Player中添加一个名为is_owner的布尔值/ tinyint列,但我可以预见这可能导致某些讨厌的视图和控制器代码。 我想知道是否有人遇到过类似的情况,也许有什么建议或可以为我提供一些好的在线资源以阅读STI?     

解决方法

        也许您应该将
Player
Owner
视为
Agent
Agency
之间的关系。因此,
Agent
拥有
Agency
Agent
Agency
的游戏。因此,您可能会介绍角色的概念,并因此介绍
Player
Owner
从中继承的
Role
模型。问题是:您是否曾经想使用
Role
模型?还是您的应用程序是关于所有者和玩家的,除了一些共同的属性,它们是两种完全不同的事物? 如果它们是两个不同的事物,则应使它们成为两个不同的模型。如果两个模型之间有一些代码重复,则可以使用一个(或多个)mixin在它们之间共享代码。 总的来说,我更喜欢组合而不是继承。首先,继承看起来是在类之间共享代码的一种优雅方式,但并非如此。继承是关于类型和接口的。因此,您需要根据界面进行耦合。这是模型进一步开发的强大约束。 仅在类之间存在真正的
is_a
关系而不是
shares_some_code_with
关系时才使用继承。更重要的是:只有在对我有技术优势的情况下,我才使用它。否则,有更好的方法可以在Ruby中的类之间共享代码。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...