Ad

Laravel Relationships And Indexes Between Matches, Teams, Players

- 1 answer

I'm struggling thinking about using a clean way to set a working relationship in Laravel between three models.

There are tons of Matches, which always contain 2 Teams where every team has 5 Players.
Note: Players aren't users, so every match will generate new teams and players.

Matches

class Match extends Model
{
    public function teams()
    {
        return $this->hasMany('App\Team');
    }
}

Teams

class Team extends Model
{
    public function players()
    {
        return $this->hasMany('App\Player');
    }

    public function match()
    {
        return $this->belongsTo('App\Match');
    }
}

Players

class Player extends Model
{
    public function team()
    {
        return $this->belongsTo('App\Team');
    }
}

My problem is that I can't find a solution in the lovely Laravel documentation for using a database table with two indexes.
Specific: A matches entry has a winner and a looser team. How to tell this in eloquentish to Laravel?

Matches

    Schema::create('matches', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('winner_team_id')->index();
        $table->integer('looser_team_id')->index();

Teams

    Schema::create('teams', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('player_1')->index();
        $table->integer('player_2')->index();
        $table->integer('player_3')->index();
        $table->integer('player_4')->index();
        $table->integer('player_5')->index();

Players

    Schema::create('players', function (Blueprint $table) {
        $table->increments('id');

Is this approach "unclean" or do I miss something obvious from the documentation like more relationship-based classes for the model?

Do I have to set up more tables like "match_teams" and "team_players" for a manyToMany-relationships-approach?

Ad

Answer

Based on your matches schema, I would probably modify your Matches relationship as follows:

class Match extends Model
{
    public function teamA()
    {
        return $this->hasOne('App\Team');
    }

    public function teamB()
    {
        return $this->hasOne('App\Team');
    }

    public function winningTeam()
    {
        return $this->hasOne('App\Team');
    }
}

Would assume that your match would always contain exactly two teams. And then in your schema:

Schema::create('matches', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('teama_id')->index();
    $table->integer('teamb_id')->index();
    $table->integer('winningteam_id')->index(); // Loser team is one of the ids from above ID, you would write a query scope to return the loser team.
    $table->string('result');
}
Ad
source: stackoverflow.com
Ad