Laravel 4无法为复杂的模型结构

问题描述:

第一篇文章所以在这里输出数据云:Laravel 4无法为复杂的模型结构

我建立一个统计网站,Laravel 4,并已建立了几个模型之间的关系 - 播放机,游戏,团队,PlayerData ,StatType标识

所有这些都有相应的表格: 球员:ID,姓名,TEAM_ID

games: id, home_team_id, away_team_id, week (note 2 teams in a single game) 
teams: id, name 
stat_types: id, name 
player_datas: id, player_id, stat_type_id, stat_value, game_id 

的想法是,每个球员效力于一支球队,一个星期谁扮演一次,每次统计的玩家进入每个游戏将在玩家数据表中具有一个条目(例如,玩家1,stat_id 1,值2,游戏1,玩家1,stat_id 2,值10,游戏1)

所以我想要做的是输出一个表,当有人想要查看播放器玩家show.blade.php( *代表占位符):

****更新:我已经得到了我想要通过使观察者的修改建议,但得到的第二和第三细胞出现数据像下面(在我看来)似乎效率低下?觉得我失去了一些东西

@foreach($team_fixtures as $team_fixture) 

<tr> 
    <td>{{$team_fixture->homeTeam->team_name}} vs {{$team_fixture->awayTeam->team_name}}</td> 
    <td>{{$team_fixture->playerData()->where('player_id', $player->id) 
    ->where('stat_type_id', '1') 
    ->pluck('stat_value')}}</td> 
    <td>{{$team_fixture->playerData()->where('player_id', $player->id) 
    ->where('stat_type_id', '2') 
    ->pluck('stat_value')}}</td> 
</tr> 
@endforeach 

我不能告诉我是否错过了透视表(player_data_stat_types?)或者已经拿到了关系,错了吗?如果有更好的结构方式,我会很乐意这样做,但我不确定从哪一个开始。我开始为每个$ team_fixtures做一次,但无法获得输出的统计信息。我的问题是,夹具左栏,但球员数据表有针对game_id多个条目...

我的播放器看起来像:

public function show($id) 
{ 
    $player = Player::findOrFail($id); 
    $team_fixtures = Game::where('home_team_id', '=', $player->team_id) 
        ->orWhere('away_team_id', '=', $player->team_id) 
        ->get(); 

    return View::make('site/players.show', compact('player', 'team_fixtures')); 
} 

和模型链接如下: 团队:

public function players() { 
    return $this->hasMany('Player'); 
} 

public function games() { 
    return $this->belongsToMany('Game'); 
} 

球员:

public function team() { 
    return $this->belongsTo('Team'); 
} 

public function playerData(){ 
    return $this->hasMany('PlayerData'); 
} 

游戏:

public function playerData() { 
    return $this->hasMany('PlayerData'); 
} 

public function homeTeam() 
{ 
return $this->hasOne('Team', 'id', 'home_team_id'); 
} 

public function awayTeam() 
{ 
return $this->hasOne('Team', 'id', 'away_team_id'); 
} 

public function playerData(){ 
    return $this->belongsTo('Player', 'player_id', 'id'); 
} 

PlayerData:

public function statType(){ 
    return $this->belongsTo('StatType', 'stat_id', 'id'); 
} 

public function game(){ 
    return $this->belongsTo('Game'); 
} 

StatType标识:

public function playerData(){ 
    return $this->hasMany('PlayerData'); 
} 

冷杉,你们的关系是错误的。下面是他们应该怎么看起来像:

// Player 
public function team() 
{ 
    return $this->belongsTo('Team'); 
} 

public function stats() 
{ 
    return $this->belongsToMany('StatType', 'player_datas') 
     ->withPivot('game_id', 'stat_value'); 
} 


// Team 
public function players() 
{ 
    return $this->hasMany('Player'); 
} 

public function awayGames() 
{ 
    return $this->hasMany('Game', 'away_team_id'); 
} 

public function homeGames() 
{ 
    return $this->hasMany('Game', 'home_team_id'); 
} 


// Game 
public function homeTeam() 
{ 
    return $this->belongsTo('Team', 'home_team_id'); 
} 

public function awayTeam() 
{ 
    return $this->belongsTo('Team', 'away_team_id'); 
} 

public function players() 
{ 
    return $this->belongsToMany('Player', 'player_datas') 
     ->withPivot('stat_value', 'stat_type_id'); 
} 

我不认为你需要PlayerData模式可言的,我想你的stat_types表有name,而不是value领域。

然后,实现你想要的,即。表明用户对每场比赛的表现(统计值),你想是这样的:

// controller 
$player = Player::find($id); 
$stats = $player->stats->groupBy('pivot.game_id'); 

// view 
<ul> 
    @foreach ($games as $game) 
     <li> 
     {{ $game->homeTeam->name }} vs {{ $game->awayTeam->name }} 
     <table> 
      @foreach ($stats->get($game->id) as $stat) 
      <tr><td>{{ $stat->name }}: </td><td>{{ $stat->pivot->stat_value }}</td> 
      @endforeach 
     </table> 
     </li> 
    @endforeach 
</ul> 
+0

干杯。我明白你要做什么,但是$游戏没有定义。我应该只是传递来自控制器的所有游戏或我已经在做什么?因为如果我传入$ team_fixtures(请参阅OP)并且将$ team_fixtures作为$ game来执行,那么它表示$ game-> stats-> get($ game-> id)是一个无效的foreach参数? – ExoticChimp 2014-09-05 06:33:43

+0

在我的示例中'$ games'与您的'$ team_fixtures'完全相同,我只是使用了模型的名称,所以它更易于阅读。然后,'$ game'上没有'stats','stats'是'$ player' - 嵌套的foreach中的一个关系。 – 2014-09-05 08:38:19

+0

啊对,我想我明白你的意思了 - 在游戏和玩家之间有一个数据透视表(我想我应该遵循Laravel的命名规则,摆脱'player_datas'?)并使用多对多关系来获得与玩家相关的统计信息 – ExoticChimp 2014-09-05 13:28:58

当你声明模型中的关系,你应该指明您的模型有关。在你的代码中,我看到的这至少一个例子:

// Game model 
public function teams() { 
    return $this->belongsToMany('Game'); 
} 

这确实应该与你的游戏模式,团队模式,但你在这里与游戏的游戏。尝试了这一点:

public function teams() { 
    return $this->belongsToMany('Team'); 
} 

在简单的设置,使用它可以在模型的实例,使用属性关系的方法名称,它没有其他特殊意义。这也将工作:

public function chicken() { 
    return $this->belongsToMany('Team'); 
} 

有了这个,我可以通过使用$game->chicken访问实例之间的关系,并能遍历许多Team实例。

另一个问题是Eloquent在声明关系时使用其他默认参数时依赖于约定。如果我想要关联两个模型,说ModelaModelb,那么它假定表名将是modelamodelb。此外,连接列将假定为modelb_id,例如,在modela表内。

您可以覆盖此行为(至少对于您的Game关系您至少需要执行此操作,因为您有home_team_idaway_team_id)。我是指你的documentation,但这里有一个例子:

// Game model 
public function homeTeam() 
{ 
    return $this->hasOne('Team', 'home_team_id'); 
} 

通知我也改变了你的belongsToManyhasOne,我认为这将更好地为你,更符合您要完成的任务。

+0

感谢您的答复,其实我有我的游戏和团队模式(仍然错误地)设立的相互关系,而不是他们自己,我只是在办公室复制粘贴。 我明白你的意思,所以我会根据你的建议更新模型,并尽力达到我的目标,尽管我仍然100%确定我的foreach应该是什么样子让桌子看起来像像我想要的? – ExoticChimp 2014-09-04 17:31:56