Description
I have been some time playing with the querying system for eloquent to get something done, and recently I found something that I think is a bug.
I have a table "Teams", with id and name columns. And I have a table "Matches" with local_id and visitant_id. What I want to achieve is to get all the matches a team has played, be it as local or visitant. And finally I come up with this.
On the Teams model:
class Team extends Eloquent {
public function matches_as_visitant() {
return $this->hasMany('Match', 'visitant_id');
}
}
On the Teams controller:
$team = Team::with(['matches_as_visitant' => function($query) {
$query->orWhere('local_id', '=', '2');
$query->orderBy('local_id', 'asc');
}])->find(2);
The query that is run with this is:
select * from `matches` where `matches`.`visitant_id` in (?) or `local_id` = ? order by `local_id` asc
After this I expect $team->matches_as_visitant to be actually all the matches, because the eloquent model already matches the visitant_id field and I add a orWhere part where it checks for the local_id. This should work but doesn't, I've been inspecting the framework code and I found at which point this actually "stops working".
In the HasOneOrMany class we have a method matchOneOrMany:
protected function matchOneOrMany(array $models, Collection $results, $relation, $type)
{
$dictionary = $this->buildDictionary($results);
// Once we have the dictionary we can simply spin through the parent models to
// link them up with their children using the keyed dictionary to make the
// matching very convenient and easy work. Then we'll just return them.
foreach ($models as $model)
{
$key = $model->getKey();
if (isset($dictionary[$key]))
{
$value = $this->getRelationValue($dictionary, $key, $type);
$model->setRelation($relation, $value);
}
}
return $models;
}
Basically the $results variable is a Collection with all the matches, but then the $models variable (that is then returned) only contains the matches played as visitant, and the local matches are lost.