Laravel 4无法为复杂模型结构输出数据

时间:2014-09-04 14:01:14

标签: php sql laravel-4 eloquent

首先发布的内容如下:

我正在使用Laravel 4建立一个统计网站,并建立了几个模型之间的关系 - 玩家,游戏,团队,PlayerData,StatType

所有这些都有相应的表格: 玩家:id,name,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( * 代表占位符)上查看玩家时输出一个表:

****更新:我已经通过制作Watcher建议的更改获得了我想要显示的数据,但是获得下面的第二个和第三个单元格(在我看来)似乎效率低下?想想我错过了什么

@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');
} 

2 个答案:

答案 0 :(得分:0)

当您在模型中声明关系时,您应该指定您将模型相关联的内容。在您的代码中,我至少看到了一个例子:

// 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');
}

注意我还将您的belongsToMany更改为hasOne,我认为这对您更有效,并且更符合您要完成的任务。

答案 1 :(得分:0)

冷静下来,你的关系错了。以下是它们的外观:

// 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>