繁体   English   中英

Rails:这是单表继承(STI)的用例吗?

[英]Rails: Is this a use case for Single Table Inheritance (STI)?

考虑这个设置。 请理解我们的设置更加详细,但这只是一个简单的例子。

competition其中有name 这是一年一度的比赛。
competition_instances其中有locationstarts_at
每个比赛都有name sports

例:
competition name :“超级碗”每年都有不同的competition_instances实例,但sport保持不变。
相反, competition name :“奥运会”在每场competition_instance都有不同的competition_instances和不同的sports

会是最好创建competition_sportscompetition_instance_sportscompetition_instance_sports作为一个子类competition_sports

目标 :使用competition_instance_sports记录(如果存在),否则使用competition_sports记录。 在我们的真实世界应用中,每个比赛/比赛实例可以有20-50个运动记录。 我们怎样才能最好地实现?

根据我对这个问题的理解,我无法看到STI在这种情况下会有什么帮助。 但是,连接表将为您提供所需的位置。

我建议创建一个新的表sports ,这个模型将具有每项运动的所有具体细节。 competition_instance.rb将有一个/多个sport.rb competiton.rb将通过competition_instance.rb进行多项sports

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_timeevent_end_time )设置特定属性。

我只想到这样的情况,那里有标准的体育运动,这些体育运动总是在奥运会上,还有一些是加入的,例如东道国提出的那些。

我会以“反向方式”使用多态关联

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

针对“这是STI的用例”的原始问题,如果没有看到环境的完全复杂性,很难说这是否存在。 但是这里有一些事情需要考虑:

摘自在Rails中使用单表继承的方式(和何时) - eugenius blog

在处理共享大部分相同功能和数据字段的模型类时,应考虑 STI,但您希望对单独扩展或添加每个类进行更精细的控制。 STI允许您在编写专用功能时将数据保存在单个表中,而不是重复代码或放弃单个功能。

你已经简化了你的例子,但听起来像competitioncompetition_instance本质上不是同一个对象,行为差异很小。 根据您所描述的内容,我可能会将这些对象重命名为eventcompetition ,或者在说明这些对象实际代表的内容方面对您更有意义。 我认为“奥运会”是一项普通活动,而“100米短跑”则是在奥运会上举行的比赛。 或者“SuperBowl”仅在2014年举办了一场“SuperBowl XLIX”比赛。

您还使用database-normalization标记了此问题,STI无法提供帮助。 如果您的共享对象之间的属性略有不同,那么到处都会出现空字段。

我在这里向您推荐其他答案,看看您应该如何将这些对象设置为符合要求。

这不是单表继承的情况,因为competition_instance不能代替competition ,1 competition可以有很多competition_instances实例。 所以你有3个表:

competitions
sports
competition_instances

competition_instances有一个外键competitions ,因为:1间competition可以有很多competition_instances但每个competition_instance都有一个确切的competition

无论是将sportscompetitions还是competition_instances实体相关,都取决于您的用例的具体限制。 我并不确切地知道你的意思是“每场competition/competition_instance实例可以有20-50个sport记录”。 我希望每个competition_instance到有一个确切的sport ,所以你可能会离开它,否则你可能会附加集合sportscompetition为好,这样您就可以获取新的competitionssport之前还有一个competition_instance 我需要有关您的用例的更多详细信息,以便为您提供进一步的建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM