考虑这个设置。请理解我们的设置更加详细,但这只是一个简单的例子。
competition
有name
。这是一年一度的比赛。
competition_instances
location
,starts_at
每场比赛的sports
都有name
。
例:
competition
。name
:“超级碗”每年都有不同的competition_instances
,但sport
保持不变。
相反,competition
。name
:“奥运会”在每个competition_instances
中有不同的sports
和不同的competition_instance
。
最好使用competition_sports
创建competition_instance_sports
和competition_instance_sports
作为competition_sports
的子类吗?
目标:如果存在,请使用competition_instance_sports
条记录,否则请使用competition_sports
记录。在我们的真实世界应用中,每个比赛/比赛实例可以有20-50个运动记录。我们怎样才能最好地实现?
答案 0 :(得分:2)
根据我对这个问题的理解,我无法看到STI在这种情况下会有什么帮助。但是,联接表将为您提供所需的位置。
我建议创建一个新表sports
,此模型将包含每项运动的所有具体细节。 competition_instance.rb
将有一个/多个sport.rb
。 competiton.rb
会有很多sports
到competition_instance.rb
。
<强> competition.rb 强>
Class Competition < ActiveRecord::Base
has_many :competition_instances
has_many :sports, through: :competition_instances
end
<强> competition_instance.rb 强>
Class CompetitionInstance < ActiveRecord::Base
belongs_to :competition
belongs_to :sport
end
<强> sport.rb 强>
Class Sport < ActiveRecord::Base
has_many :competition_instances
end
通过使用此设计,您将能够实现以下目标:
1-您将在数据库中拥有预定义的运动及其特定属性。
2-每场比赛将有.sports
,这将为本届奥运会比赛提供所有体育赛事。
3-您将能够在竞赛实例表中为每个竞赛实例(例如event_start_time
和event_end_time
)设置特定属性。
答案 1 :(得分:1)
我只是想到这样的情况,即总会有奥运会的标准运动和一些加入的运动,例如东道国提出的运动。
我会在Polymorphic Associations中使用"reverse manner"。
class Competition < ActiveRecord::Base
has_many :competition_instances
has_many :competition_sports, as: :event
end
class CompetitionInstance < ActiveRecord::Base
belongs_to :competition
has_many :competition_sports, as: :event
def events_array # neater by sacrificing ActiveRecord methods
competition.competition_sports + competition_sports
end
def events # messier, returns ActiveRecord relationship
CompetitionSport.where( " ( event_id = ? AND event_type = 'Competition' ) OR
( event_id = ? AND event_type = 'CompetitionInstance')", competition_id, id )
end
end
class Sport < ActiveRecord::Base
has_many :events, as: :competition_sport
end
class CompetitionSport < ActiveRecord::Base
belongs_to :sport
belongs_to :event, polymorphic: true
end
这允许:
competition.competition_sports # standard sports
competition_instance.competition_sports # only those specific for this instance
competition_instance.events # includes sports from both
答案 2 :(得分:1)
针对“这是STI的用例”的原始问题,如果没有看到环境的完全复杂性,很难说这是否存在。但是这里有一些事情需要考虑:
摘自How (and When) to Use Single Table Inheritance in Rails - eugenius blog:
在处理共享大部分相同的功能和数据字段 的模型类时,STI应该被视为,但您需要更精细的控制过度扩展或逐个添加到每个类。 STI允许您在编写专用功能时将数据保存在单个表中,而不是复制代码或放弃单个功能。
您已经简化了示例,但听起来像b
和competition
基本上不是同一个对象,行为差异很小。根据您所描述的内容,我可能会将这些对象重命名为competition_instance
和event
,或者在说明这些对象实际表示的内容方面对您更有意义。我认为“奥运会”是一项普通活动,而“100米短跑”则是在奥运会上举行的比赛。或者“SuperBowl”仅在2014年举办了一场比赛,“SuperBowl XLIX”。
您还使用competition
标记了此问题,STI无法提供帮助。如果您的共享对象之间的属性略有不同,那么到处都会出现空字段。
我在这里向您推荐其他答案,看看您应该如何设置这些对象以达到所需的效果。
答案 3 :(得分:0)
这不是单表继承的情况,因为competition_instance
不能替代competition
而1 competition
可以有很多competition_instances
。所以你有3个表:
competitions
sports
competition_instances
competition_instances
有competitions
的外键,因为1 competition
可以有多个competition_instances
,但每个competition_instance
只有一个competition
。< / p>
是否将sports
附加到competitions
或competition_instances
取决于您的用例的具体限制。我并不确切地知道你的意思是“每个competition/competition_instance
可以有20-50个sport
记录”。我希望每个competition_instance
只有一个sport
,因此您可以将其留在那里,或者您也可以将sports
的集合附加到competition
,所以您可以在competitions
之前按sport
检索新的competition_instance
。我需要有关您的用例的更多详细信息,以便为您提供进一步的建议。