简体   繁体   中英

Laravel 5.1 Eloquent Relationship for a table with two user id columns

I've got a sports app that has a list of Competitors (competitors table ) and a Match (matches table) where in a match there are two competitors so the matches table has a column for player with hasOne competitor relationship , and another column for opponent with hasOne competitor relationship , which seemed okay at first, but the relationships for the Match model would have to look like this:

Current Match Model

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

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

Instead of something like this:

Ideal Match Model

public function players()
{
    return $this->hasMany('App\Competitor');
}

and the relationship for the Competitors model gets even uglier with:

Current Competitors Model

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

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

Instead of something like this:

Ideal Competitors Model

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

If there weren't two columns one for each player this would look the way it should and get all the players matches, or get the player(s) in a match using eager loading or whatever, but that isn't the case.

I'd like to be able to just use belongsTo match and hasMany competitors like I've outlined above, but I'm not sure how to make this work other than just get each result separately then merging them before carrying on, or if it is even possible to do the ideal? Does it mean reconfiguring the database tables?

I think you should reconfigure the tables so that a Competitor holds a foreign key for the Match and not the other way around and then just add something like a competitor_type field that can have either a player or opponent value. That way a Match hasMany Competitor , a Competitor belongsTo a Match and a Competitor can either be a player or opponent .

UPDATE

For the Match model to have a reference to each type of Competitor , you can do the following:

public function competitors()
{
    return $this->hasMany('App\Competitor');
}

public function player()
{
    return $this->hasOne('App\Competitor')->where('competitor_type', 'player');
}

public function opponent()
{
    return $this->hasOne('App\Competitor')->where('competitor_type', 'opponent');
}

So you can use Eloquent methods on it and do something like: $match->player->name or $match->opponent->name .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM