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.