Reputation: 489
Using Laravel 5.4, I have a table Teams and another table Matches Each match has TEAM HOME ID and TEAM AWAY ID
I found this great trick to merge in such cases to find all the matches played by a team either at home or away. But it does not seem to work.
/**
* The matches that this team has played at home.
*/
public function matchesHome()
{
return $this->hasMany('App\Match', 'team_home_id', 'id');
}
/**
* The matches that this team has played away.
*/
public function matchesAway()
{
return $this->hasMany('App\Match', 'team_away_id', 'id');
}
/**
* The matches that this team has played.
*/
public function matches()
{
$matchesPlayedHome = $this->matchesHome();
$matchesPlayedAway = $this->matchesAway();
// Merge collections and return single collection.
return $matchesPlayedHome->merge($matchesPlayedAway); // cannot get this to work | Call to undefined method Illuminate\Database\Query\Builder::merge()
}
The error I am getting is Call to undefined function merge Call to undefined method Illuminate\Database\Query\Builder::merge()
Please help Thanks
..................
I have even tried eager loading, in that case the error becomes
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
public function matches()
{
$matches = Team::with('matchesHome', 'matchesAway')->get();
return $matches;
}
Upvotes: 2
Views: 3211
Reputation: 489
This is how I solved the problem. The $appends answer in another post was not clear so let me explain below.
If you don't add any method to $appends, Laravel thinks that it is also a relationship attribute and gives an error Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
Because it is looking for a relationship which it does not get. That is why if we add $appends we can have this following code working.
If anyone lands in this situation this is how I solved it.
protected $appends = ['matches'];
/**
* The matches that this team has played at home.
*/
public function matchesHome()
{
return $this->hasMany('App\Match', 'team_home_id', 'id');
}
/**
* The matches that this team has played away.
*/
public function matchesAway()
{
return $this->hasMany('App\Match', 'team_away_id', 'id');
}
/**
* This function is used by the appends to append two attributes
*/
public function getMatchesAttribute()
{
return $this->matchesHome->merge($this->matchesAway);
}
We can also replace this with Eager loading and it will work fine.
Upvotes: 2
Reputation: 10517
I think your syntax is a bit off:
function matches() {
return $this->matchesHome->merge($this->matchesAway);
}
Upvotes: 0