【问题标题】:Designing the relationship between models where the child model attributes vary based on the "type" of its parent设计子模型属性根据其父模型的“类型”而变化的模型之间的关系
【发布时间】:2014-10-22 19:42:06
【问题描述】:

当子模型的属性会根据它所属的父类型而变化时,我应该如何设计模型之间的关系?

例如: Player has_many :projections 其中 Projection 实例上的字段将根据它所属的 Player 的“类型”而有所不同。

class Player < ActiveRecord::Base
  attr_accessible :name, :position, :team
  has_many :projections
  validates_uniqueness_of :name, :scope => [:position, :team]
end

class Projection < ActiveRecord::Base
  attr_accessible :ppr, :salary, :score, :week, :player_id
  belongs_to :player
  validates_uniqueness_of :ppr, :scope => [:week, :player_id]
end

所以,我想修改它并向 Projection 添加额外的属性/字段,其中字段根据 Player 模型的“位置”属性而有所不同

要添加的新字段示例如下:

:passing, :completions, :receptions, :targets

位置为“QB”的玩家的投影将如下所示:

Projection.create(passing: 300, completions: 30, week: 8, player_id: 1)

虽然位置为“WR”的玩家的投影看起来像这样:

Projection.create(receptions: 5, targets: 9, week: 8, player_id: 2)

id为1的玩家属于“QB”位置类型,而id为2的玩家属于“WR”类型

它们仍然是“投影”,只是它们会根据玩家的位置保存不同类型的数据。我当前的模式不考虑玩家的位置。目前,它们都具有相同的属性。修改现有模式以考虑这些新数据点的正确方法是什么?我担心在修改以添加此新功能时可能会破坏现有代码。

【问题讨论】:

    标签: ruby-on-rails-3 inheritance activerecord database-design


    【解决方案1】:

    如果不了解您的应用程序和用例的更多信息,很难给出明确的答案。

    但根据您的描述,我建议您在projections 表中添加四个新列(即passing、completions、receptions 和targets)。然后根据 Player 的位置,根据需要填充和读取它们,而有些值可以保持NULL。

    如果您需要为不同玩家的投影自定义行为(如验证),那么引入投影类型可能会有所帮助(即单表继承)。无论如何,以一种或另一种形式记住玩家在投影上的位置可能是一个好主意,以防玩家在某个时候改变他们的位置。但也许您不需要它,因为您可以只显示实际包含给定投影值的列。

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 2016-02-12
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多