【问题标题】:How can I have a relationship between models based off an attributes value?如何根据属性值建立模型之间的关系?
【发布时间】:2023-03-17 16:30:02
【问题描述】:

我有以下三个模型...

播放器

id:integer
first_name:string
last_name:string

学校

id:integer
short_name:string
long_name:string

SchoolRosterSlot

id:integer
season:integer
jersey:string
position:string
active:boolean

最初我打算将球衣、位置、学校 ID 存储在 Player 模型中。但是,我改变了这一点,因为我认为将这些信息输入到 Player 模型中是多余的,并将其插入到 SchoolRosterSlot 模型中,因为我想存储有关球员的赛季信息。 (球员的位置、球衣和学校都会随着赛季的变化而变化)。

我的问题是如何设置我的关联,以便我可以通过@player.school 访问玩家的学校?或@player.jersey... 还是在学校和玩家之间建立直接关联并插入名册插槽记录也更好,即使这会记录两次信息?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 associations rails-activerecord


    【解决方案1】:

    一般来说,您希望尽可能避免存储重复信息。

    您可以尝试将 school_roster_slot_id 添加到 Player 并将 school_id 添加到 SchoolRosterSlot,然后将其添加到模型中:

    class SchoolRosterSlot
      belongs_to :school
    end
    
    class Player
      belongs_to :school_roster_slot
      has_one :school, through: :school_roster:slot
    end
    

    这将创建一个player.school 方法。如果您还想获得player.jerseyplayer.position,您也可以将其添加到播放器:

    delegate :position, :jersey, to :school_roster_slot
    

    这实际上与创建以下两个方法相同:

    def jersey
      school_roster_slot.jersey
    end
    
    def position
      school_roster_slot.position
    end
    

    我不知道您是否要存储有关球员位置和球衣的历史信息(例如,当球员更换位置和球衣时,您是否仍要存储有关其旧位置的信息?),但如果是这种情况,您可能需要做一些事情,比如创建一个名为Season 的附加模型,它位于PlayerSchoolRosterSlot 之间。或者,您可以将start_dateend_date 添加到SchoolRosterSlot 以表示玩家何时开始并离开该位置?

    【讨论】:

    • 谢谢!我正要跳回到这个,看看我能不能让它工作。是的,我确实想存储历史信息,例如每个赛季的学校、球衣和位置。这有点让我失望。我可能正在考虑制作一个 SchoolRosterHistorical,它会在进入新的 SchoolRosterSlot 赛季时插入一个记录。但这种方法似乎也存在一些潜在问题。
    • 是否可以在has_one :school 关联中添加条件语句?所以我会有某种方式在赛季中按 desc 顺序为球员排序记录,然后将查询限制为 1 个返回。这样我就能得到最近一季的记录?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 2012-05-08
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多