Fix Eloquent eager loading matching.
This commit is contained in:
parent
b65fa7040d
commit
94948cf675
|
@ -66,12 +66,11 @@ public function first($columns = array('*'))
|
||||||
* Get all of the model results for the query.
|
* Get all of the model results for the query.
|
||||||
*
|
*
|
||||||
* @param array $columns
|
* @param array $columns
|
||||||
* @param bool $keyed
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function get($columns = array('*'), $keyed = true)
|
public function get($columns = array('*'))
|
||||||
{
|
{
|
||||||
return $this->hydrate($this->model, $this->table->get($columns), $keyed);
|
return $this->hydrate($this->model, $this->table->get($columns));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,10 +99,9 @@ public function paginate($per_page = null, $columns = array('*'))
|
||||||
*
|
*
|
||||||
* @param Model $model
|
* @param Model $model
|
||||||
* @param array $results
|
* @param array $results
|
||||||
* @param bool $keyed
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function hydrate($model, $results, $keyed = true)
|
public function hydrate($model, $results)
|
||||||
{
|
{
|
||||||
$class = get_class($model);
|
$class = get_class($model);
|
||||||
|
|
||||||
|
@ -128,17 +126,7 @@ public function hydrate($model, $results, $keyed = true)
|
||||||
|
|
||||||
$new->original = $new->attributes;
|
$new->original = $new->attributes;
|
||||||
|
|
||||||
// Typically, the resulting models are keyed by their primary key, but it
|
$models[] = $new;
|
||||||
// may be useful to not do this in some circumstances such as when we
|
|
||||||
// are eager loading a *-to-* relationships which has duplicates.
|
|
||||||
if ($keyed)
|
|
||||||
{
|
|
||||||
$models[$result[$this->model->key()]] = $new;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$models[] = $new;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($results) > 0)
|
if (count($results) > 0)
|
||||||
|
@ -199,17 +187,7 @@ protected function load(&$results, $relationship, $constraints)
|
||||||
|
|
||||||
$query->initialize($results, $relationship);
|
$query->initialize($results, $relationship);
|
||||||
|
|
||||||
// If we're eager loading a many-to-many relationship we will disable
|
$query->match($relationship, $results, $query->get());
|
||||||
// the primary key indexing on the hydration since there could be
|
|
||||||
// roles shared across users and we don't want to overwrite.
|
|
||||||
if ( ! $query instanceof Has_Many_And_Belongs_To)
|
|
||||||
{
|
|
||||||
$query->match($relationship, $results, $query->get());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$query->match($relationship, $results, $query->get(array('*'), false));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -87,9 +87,14 @@ public function match($relationship, &$children, $parents)
|
||||||
|
|
||||||
foreach ($children as &$child)
|
foreach ($children as &$child)
|
||||||
{
|
{
|
||||||
if (array_key_exists($child->$foreign, $parents))
|
$parent = array_first($parents, function($k, $v) use ($child, $foreign)
|
||||||
{
|
{
|
||||||
$child->relationships[$relationship] = $parents[$child->$foreign];
|
return $v->get_key() == $child->$foreign;
|
||||||
|
});
|
||||||
|
|
||||||
|
if ( ! is_null($parent))
|
||||||
|
{
|
||||||
|
$child->relationships[$relationship] = $parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,9 +91,14 @@ public function match($relationship, &$parents, $children)
|
||||||
{
|
{
|
||||||
$foreign = $this->foreign_key();
|
$foreign = $this->foreign_key();
|
||||||
|
|
||||||
foreach ($children as $key => $child)
|
foreach ($parents as &$parent)
|
||||||
{
|
{
|
||||||
$parents[$child->$foreign]->relationships[$relationship][$child->get_key()] = $child;
|
$matching = array_filter($children, function($v) use ($parent, $foreign)
|
||||||
|
{
|
||||||
|
return $v->$foreign == $parent->get_key();
|
||||||
|
});
|
||||||
|
|
||||||
|
$parent->relationships[$relationship] = $matching;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -311,7 +311,7 @@ public function initialize(&$parents, $relationship)
|
||||||
*/
|
*/
|
||||||
public function eagerly_constrain($results)
|
public function eagerly_constrain($results)
|
||||||
{
|
{
|
||||||
$this->table->where_in($this->joining.'.'.$this->foreign_key(), array_keys($results));
|
$this->table->where_in($this->joining.'.'.$this->foreign_key(), $this->keys($results));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -325,14 +325,14 @@ public function match($relationship, &$parents, $children)
|
||||||
{
|
{
|
||||||
$foreign = $this->foreign_key();
|
$foreign = $this->foreign_key();
|
||||||
|
|
||||||
// For each child we'll just get the parent that connects to the child and set the
|
foreach ($parents as &$parent)
|
||||||
// child model on the relationship array using the keys. Once we're done looping
|
|
||||||
// through the children all of the proper relations will be set.
|
|
||||||
foreach ($children as $key => $child)
|
|
||||||
{
|
{
|
||||||
$parent =& $parents[$child->pivot->$foreign];
|
$matching = array_filter($children, function($v) use ($parent, $foreign)
|
||||||
|
{
|
||||||
|
return $v->pivot->$foreign == $parent->get_key();
|
||||||
|
});
|
||||||
|
|
||||||
$parent->relationships[$relationship][$child->{$child->key()}] = $child;
|
$parent->relationships[$relationship] = $matching;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,14 @@ public function match($relationship, &$parents, $children)
|
||||||
{
|
{
|
||||||
$foreign = $this->foreign_key();
|
$foreign = $this->foreign_key();
|
||||||
|
|
||||||
foreach ($children as $key => $child)
|
foreach ($parents as &$parent)
|
||||||
{
|
{
|
||||||
$parents[$child->$foreign]->relationships[$relationship] = $child;
|
$matching = array_first($children, function($k, $v) use ($parent, $foreign)
|
||||||
|
{
|
||||||
|
return $v->$foreign == $parent->get_key();
|
||||||
|
});
|
||||||
|
|
||||||
|
$parent->relationships[$relationship] = $matching;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ protected function constrain()
|
||||||
*/
|
*/
|
||||||
public function eagerly_constrain($results)
|
public function eagerly_constrain($results)
|
||||||
{
|
{
|
||||||
$this->table->where_in($this->foreign_key(), array_keys($results));
|
$this->table->where_in($this->foreign_key(), $this->keys($results));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -101,4 +101,22 @@ public function foreign_key()
|
||||||
return static::foreign($this->base, $this->foreign);
|
return static::foreign($this->base, $this->foreign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gather all the primary keys from a result set.
|
||||||
|
*
|
||||||
|
* @param array $results
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function keys($results)
|
||||||
|
{
|
||||||
|
$keys = array();
|
||||||
|
|
||||||
|
foreach ($results as $result)
|
||||||
|
{
|
||||||
|
$keys[] = $result->get_key();
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_unique($keys);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ public static function exception($exception, $trace = true)
|
||||||
{
|
{
|
||||||
static::log($exception);
|
static::log($exception);
|
||||||
|
|
||||||
ob_get_level() and ob_end_clean();
|
//ob_get_level() and ob_end_clean();
|
||||||
|
|
||||||
// If detailed errors are enabled, we'll just format the exception into
|
// If detailed errors are enabled, we'll just format the exception into
|
||||||
// a simple error message and display it on the screen. We don't use a
|
// a simple error message and display it on the screen. We don't use a
|
||||||
|
|
Loading…
Reference in New Issue