nklvjvc's avatar

Multiple foreign id, Team-Matches

Hi, so I have a table with 'matches' where are team1_id, team2_id, result. Both team1_id and team2_id have foreign key to id from 'teams' table.

In match model I have: team1 and team2 methods are for using values from their database and not just displaying id.

public function team(): BelongsTo
{
    return $this->belongsTo(Team::class);
}

public function team1(): BelongsTo
{
    return $this->belongsTo(Team::class, 'team1_id');
}

public function team2(): BelongsTo
{
    return $this->belongsTo(Team::class, 'team2_id');
}

In team model I have:

public function matches(): HasMany
{
    return $this->hasMany(Match::class, 'team1_id');
}

Controller is: return view('team', [ 'matches' => $team->matches ]);

So everything works fine except when using in Team model return $this->hasMany(Match::class); This shows error as there is not team_id in table return $this->hasMany(Match::class, 'team1_id'); If I use this one, on page of team it shows me Matches where team is team1_id. And on page of another team where id = team2_id would be blank

Is there a way to make it something like return $this->hasMany(Match::class, 'team1_id' OR 'team2_id');

0 likes
3 replies
MohamedTammam's avatar
$this->hasMany(Match::class, 'team1_id')->orWhere('matches.id', 'team2_id');
martinbean's avatar

@nklvjvc You’d normally have some a “game” or “match” model that has home team and away team relations.

I’d strongly suggest you name your model Game instead of Match, as match became a reserved keyword from PHP 8.0. I know this as I used to have an application with a Match model that broke trying to upgrade from PHP 7.4 to PHP 8.0. So I’m surprised you haven’t already been bitten by this; it leads me to think you’re maybe using a massively outdated version of Laravel and/or PHP. You should be using the latest versions of both.

Once you have a Game with homeTeam and awayTeam relations (and home_team_id and away_team_id columns in the database), you could add a local scope to your Game model to find all games for a particular team:

public function scopeForTeam(Builder $query, Team $team): Builder
{
    return $query->where(function (Builder $query) use ($team) {
        $query->where('home_team_id', '=', $team->getKey());
        $query->orWhere('away_team_id', '=', $team->getKey());
    });
}

You can then use this scope like this:

$games = Game::query()->forTeam($team)->get();

This will fetch all games where either the home team or away team matches the given $team argument.

Unfortunately, you won’t be able to put a single relation on your Team model to get games because as you can see above, you need to check two columns for the team ID.

Please or to participate in this conversation.