Cakephp 3 - 玩家/匹配关系的正确关联类型是什么?

时间:2015-03-31 00:44:26

标签: cakephp cakephp-3.0

在我的cakephp3应用程序中,我有一个Players表和一个Matches表,记录两个玩家之间完成的每​​个匹配。我的表匹配的结构是:

  • ID
  • created< - datetime
  • winner_id< - 赢得比赛的球员的身份。
  • loser_id< - 输掉比赛的球员的身份。

我已经定义了玩家和匹配之间的关联,如下所示:

// in src/Model/Table/PlayersTable.php
$this->hasMany('Victories', [
    'className' => 'Matches',
    'foreignKey' => 'winner_id'
]);
$this->hasMany('Losses', [
    'className' => 'Matches',
    'foreignKey' => 'loser_id'
]);

当我想要找回所有比赛的球员时,我会这样做:

// in src/Controller/PlayersController.php
$player = $this->Players->findById($user_id)->contain(['Victories', 'Losses'])->first();

但这不是很方便,因为要在一个地方获得所有玩家的比赛,我必须合并$player->victories$player->losses。 另外,我不能轻易地执行简单的请求,例如“让最后一场比赛获得50名球员”。

所以我觉得我的数据库模式不理想,我可以改进。但我真的不明白。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

正确的架构是删除匹配项中的winner_idloser_id,并将它们放入另一个可以称为contenders的表中

表格竞争者:

* match_id
* player_id
* has_won (boolean)

您使用hasMany

将表格匹配与竞争者相关联
$this->hasMany('Contenders');

现在,您还可以使用belongsToMany关联将Matchers与玩家相关联:

$this->belongsToMany('Players', ['through' => 'Contenders']);

您还可以将玩家表关联到胜利和损失:

$this->belongsToMany('Victories', [
    'className' => 'Matches',
    'through' => 'Contenders'
    'conditions' => ['Contenders.has_won' => true]
]);

$this->belongsToMany('Losses', [
    'className' => 'Matches',
    'through' => 'Contenders'
    'conditions' => ['Contenders.has_won' => false]
]);

最后,您还可以通过添加另一个belognsToMany来了解玩家的所有匹配项:

$this->belongsToMany('Matches');