如何在Rails的Active Record模型中实现多对多?

时间:2018-11-05 20:13:05

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

我正在为学校做Rails项目,其中一项要求是我在模型中使用多对多关系。我到处都看到的示例非常简单并且很有意义,但是我只是不能将其并入我正在做的事情中。

我正在做的项目是一个体育博彩网站,基本上,您会选择Fighter A或Fighter B赢,赔率将显示在页面上并列出潜在的支付金额,等等。

到目前为止,我已经创建了一个 Fighter Fight Event 模型,并且很难使它们彼此协同工作。这是我所拥有的:

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. 我还想使用Fights表来检索Fighters的名称,而无需将其实际保存到Fight模型中(Fighter名称在Fighter模型内部)。例如:“ Fight.find(2).Fighters.names”-无论如何都会达到这种效果。

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

1 个答案:

答案 0 :(得分:0)

您没有提到您愿意为给定的战斗机进行战斗,因此使用该假设,您可以摆脱Fighter模型中的所有内容并且它应该起作用(假设您的模式有效)。 (如果您DID想要获得战斗机的所有战斗权,它会稍微复杂一些。如果您确实需要,我可以提供帮助):

这样做:

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