【问题标题】:How to implement Many-to-Many in Active Record models in Rails?如何在 Rails 的 Active Record 模型中实现多对多?
【发布时间】:2018-11-05 20:13:04
【问题描述】:

我正在为学校做一个 Rails 项目,其中一个要求是我在我的模型中使用多对多关系。我所看到的所有示例都非常简单且有意义,但我无法将其纳入我的具体工作中。

我正在做的项目是一个体育博彩网站,基本上你会选择战斗机 A 或战斗机 B 获胜,赔率会显示在页面上,列出潜在的支付金额等。

到目前为止,我已经创建了一个 FighterFightEvent 模型,要让它们相互配合非常困难.这是我所拥有的:

class Event < ApplicationRecord
  has_many :fights
end

class Fight < ApplicationRecord
  belongs_to :red_corner, :class_name => "Fighter", :foreign_key => 'red_id'
  belongs_to :blue_corner, :class_name => "Fighter", :foreign_key = 'blue_id'
  belongs_to :event
end

class Fighter < ApplicationRecord
  has_one :red_corner, :class_name => "Fighter", :foreign_key => 'red_id'
  has_one :blue_corner, :class_name => "Fighter", :foreign_key => 'blue_id'
end

如果有人对此感到困惑,只是为了扩展这一点,一个活动每晚会举行很多场战斗,比如说大约 10 场。一场战斗由 2 名战士组成(红色角落的对手和蓝色角落的对手,不确定如果我在那里正确处理了 FK,但我相信它到目前为止有效)。

我需要的是:

  1. 这里我可以合并多对多的情况。以某种方式将我的事件模型包含在其中会很好,这样我就可以返回特定事件中的战斗列表。 (而不是将多个值加载到我的事件表的一列中)。
  2. 我还想使用 Fights 表来检索 Fighters 的名称,而不是将它们实际保存到 Fight 模型中(Fighters 名称在 Fighter 模型中)。例如:“Fight.find(2).Fighters.names”——无论如何都是这样的。

如果需要,也可以发布我的架构。

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-5 associations model-associations


    【解决方案1】:

    您没有提到您希望为给定的战斗机进行战斗,因此在此假设下,您可以摆脱 Fighter 模型中的所有内容并且它应该可以工作(假设您的架构有效)。 (如果您确实想为一名战士完成所有战斗,那会稍微复杂一些。如果您真的需要,我可以提供帮助):

    这样做:

    class Event < ApplicationRecord
      has_many :fights
    end
    
    class Fight < ApplicationRecord
      belongs_to :event
      belongs_to :red_corner, :class_name => "Fighter", :foreign_key => 'red_id'
      belongs_to :blue_corner, :class_name => "Fighter", :foreign_key => 'blue_id'
    end
    
    class Fighter < ApplicationRecord
    
    end
    

    允许我做:

    fighter1 = Fighter.create(name: "Bob")
    => #<Fighter id: 1, name: "Bob", created_at: "2018-11-06 00:52:05", updated_at: "2018-11-06 00:52:05">
    
    fighter2 = Fighter.create(name: "Jack")
    => #<Fighter id: 2, name: "Jack", created_at: "2018-11-06 00:52:06", updated_at: "2018-11-06 00:52:06">
    
    event = Event.create(name: "Super fight day")
    => #<Event id: 1, name: "Super fight day", created_at: "2018-11-06 00:52:09", updated_at: "2018-11-06 00:52:09">
    
    fight = event.fights.create(red_corner: fighter1, blue_corner: fighter2)
    => #<Fight id: 1, event_id: 1, red_id: 1, blue_id: 2, created_at: "2018-11-06 00:52:09", updated_at: "2018-11-06 
    
    puts "#{Event.first.fights.first.red_corner.name} vs #{Event.first.fights.first.blue_corner.name}"
    Bob vs Jack
    

    【讨论】:

    • 哦,哇,确实有效,谢谢!所以我真的不需要在我的战士模型中定义任何东西吗?为什么会这样?另外,我可以在这里添加与多对多相关的任何内容吗?
    • 在 Fighter 模型中不需要任何东西,因为 Fight 和 Fighter 之间的关系在这里是单向的,Fight 是父级,Fighter 是子级。您不需要在您的场景中引用 Fighter from the Fighter,只需引用来自 Event 的 Fighter。执行 Fighter.first.event 将不起作用,因为您尚未在 Fighter 中定义该活动记录关系。您只需在要添加 Active Record 关联助手的模型中定义这些关系。这有意义吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    相关资源
    最近更新 更多