Skip to content

Commit cc4514e

Browse files
committed
Fix bug in many to many eager loading.
Signed-off-by: Taylor Otwell <taylorotwell@gmail.com>
1 parent 3e00ce2 commit cc4514e

File tree

1 file changed

+33
-12
lines changed

1 file changed

+33
-12
lines changed

laravel/database/eloquent/query.php

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
<?php namespace Laravel\Database\Eloquent; use Laravel\Database;
1+
<?php namespace Laravel\Database\Eloquent;
2+
3+
use Laravel\Database;
4+
use Laravel\Database\Eloquent\Relationships\Has_Many_And_Belongs_To;
25

36
class Query {
47

@@ -54,7 +57,7 @@ public function __construct($model)
5457
*/
5558
public function first($columns = array('*'))
5659
{
57-
$results = $this->hydrate($this->model, $this->table->take(1)->get($columns, false));
60+
$results = $this->hydrate($this->model, $this->table->take(1)->get($columns));
5861

5962
return (count($results) > 0) ? head($results) : null;
6063
}
@@ -63,12 +66,12 @@ public function first($columns = array('*'))
6366
* Get all of the model results for the query.
6467
*
6568
* @param array $columns
66-
* @param bool $include
69+
* @param bool $keyed
6770
* @return array
6871
*/
69-
public function get($columns = array('*'), $include = true)
72+
public function get($columns = array('*'), $keyed = true)
7073
{
71-
return $this->hydrate($this->model, $this->table->get($columns), $include);
74+
return $this->hydrate($this->model, $this->table->get($columns), $keyed);
7275
}
7376

7477
/**
@@ -97,9 +100,10 @@ public function paginate($per_page = null, $columns = array('*'))
97100
*
98101
* @param Model $model
99102
* @param array $results
103+
* @param bool $keyed
100104
* @return array
101105
*/
102-
public function hydrate($model, $results, $include = true)
106+
public function hydrate($model, $results, $keyed = true)
103107
{
104108
$class = get_class($model);
105109

@@ -124,10 +128,20 @@ public function hydrate($model, $results, $include = true)
124128

125129
$new->original = $new->attributes;
126130

127-
$models[$result[$this->model->key()]] = $new;
131+
// Typically, the resulting models are keyed by their primary key, but it
132+
// may be useful to not do this in some circumstances such as when we
133+
// are eager loading a *-to-* relationships which has duplicates.
134+
if ($keyed)
135+
{
136+
$models[$result[$this->model->key()]] = $new;
137+
}
138+
else
139+
{
140+
$models[] = $new;
141+
}
128142
}
129143

130-
if ($include and count($results) > 0)
144+
if (count($results) > 0)
131145
{
132146
foreach ($this->model_includes() as $relationship => $constraints)
133147
{
@@ -183,12 +197,19 @@ protected function load(&$results, $relationship, $constraints)
183197
$query->table->where_nested($constraints);
184198
}
185199

186-
// Before matching the models, we will initialize the relationship
187-
// to either null for single-value relationships or an array for
188-
// the multi-value relationships as their baseline value.
189200
$query->initialize($results, $relationship);
190201

191-
$query->match($relationship, $results, $query->get());
202+
// If we're eager loading a many-to-many relationship we will disable
203+
// the primary key indexing on the hydration since there could be
204+
// roles shared across users and we don't want to overwrite.
205+
if ( ! $query instanceof Has_Many_And_Belongs_To)
206+
{
207+
$query->match($relationship, $results, $query->get());
208+
}
209+
else
210+
{
211+
$query->match($relationship, $results, $query->get(array('*'), false));
212+
}
192213
}
193214

194215
/**

0 commit comments

Comments
 (0)