为了得到两列字段,我可以从一个表到另一个表使用两个外键吗



我有两个表,一个是Player,另一个是Result。我可以在Result上设置两个外键,与Player相关,这样我就可以用Result更改两个玩家的值吗?我正在开发Ruby web应用程序,根据我要添加的与足球比赛相关的结果,我将更新每个球员的字段。例如,如果分数是Player1 3-0 Player2,Player1将获得3分,而另一个为0,所以基本上从一个结果来看,我将不得不更改Player表中的两个字段。我还必须添加每个球员的进球数和进球数。我可以解决这个问题吗?例如,在结果中分配两个名称,我会检查Player表中的名称,然后使用两个外键更改字段,或者我只需要正确设置我的方法?

以下是表格:

Player
t.string :name
t.integer :win
t.integer :draw
t.integer :lose
t.integer :gs
t.integer :gt
t.integer :dr
t.integer :points
Result
t.string :name1
t.integer :goal1
t.string :name2
t.integer :goal2
t.datetime :date
t.references :player, null: false, foreign_key: true

如果我在Result中添加两个引用,可以吗?

可以。有时这是个好主意,但这里不行。您需要一个联接表。原因如下。

您需要使用两个不同的列名,并告诉Rails它们引用的表。

Result
t.string :name1
t.integer :goal1
t.string :name2
t.integer :goal2
t.datetime :date
t.references :player1,
null: false,
foreign_key: { to_table: :players }
t.references :player2,
null: false,
foreign_key: { to_table: :players }

您需要在代码中明确它们。

class Result < ApplicationRecord
belongs_to :player1, class_name: 'Player'
belongs_to :player2, class_name: 'Player'
end

在Player中把它们绑在一起是个小把戏。这样做太天真了。

class Player < ApplicationRecord
has_many :player1_results,
class_name: 'Result',
foreign_key: :player1_id
has_many :player2_results,
class_name: 'Result',
foreign_key: :player2_id
end

如果你想要玩家的所有结果怎么办?如果你想要一个结果的所有玩家怎么办?问题来了。您需要进行冗余查询或添加额外的子句,如where player1_id = :player_id or player2_id = :player_id。类似地,name1name2goal1goal2


每当您想要存储多个关联的东西时,都需要一个联接表。即使只有两个。它让生活变得轻松多了。

你有一个结果表,但结果是什么?一场比赛!有关比赛的信息存储在哪里?在结果表中。它应该是自己的桌子。

我们有三张桌子。玩家、比赛和一个表,用于存储玩家在比赛中的表现(结果(。

create_table :players do
t.string :name, null: fase
...
t.timestamps
end
create_table :matches do
t.string :name, null: false
t.datetime :date, null: false
...
t.timestamps
end
create_table :results do
t.references :player, foreign_key: true, null: false
t.references :match, foreign_key: true, null: false
t.integer :goals
end

现在有了这三块,我们可以把它们放在一起。比赛和选手通过结果相关。

class Matches < ApplicationRecord
has_many :results
has_many :players, through: :results
end
class Players < ApplicationRecord
has_many :results
has_many :matches, through: :results
end
class Results < ApplicationRecord
belongs_to :match
belongs_to :player
end

现在,如果你想在你的比赛中找到球员。。。

players = match.players

这将对结果执行联接。

如果您必须跟踪玩家1和玩家2,请将其添加到具有唯一约束的结果表中。

create_table :results do
t.references :player, foreign_key: true, null: false
t.references :match, foreign_key: true, null: false
t.integer :goals, null: false, default: 0
t.integer :player_number, null: false, default 1
# Can't have two player 1s for the same match.
# :player_number is deliberately first so this index also serves
# to index player_number.
t.index [:player_number, :match_id], unique: true
end

然后你可以得到这样的播放器1:

player = match.players.find_by!(player_number: 1)

你可以在关系中添加一些方便的方法。

class Matches < ApplicationRecord
has_many :results
has_many :players, through: :results do
def player(num)
match.players.find_by!(player_number: num)
end
end
end
player = match.players.player(1)

相关内容

最新更新