diff --git a/laravel/database/eloquent/query.php b/laravel/database/eloquent/query.php index e55e6a40..0906449e 100644 --- a/laravel/database/eloquent/query.php +++ b/laravel/database/eloquent/query.php @@ -66,12 +66,11 @@ public function first($columns = array('*')) * Get all of the model results for the query. * * @param array $columns - * @param bool $keyed * @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 array $results - * @param bool $keyed * @return array */ - public function hydrate($model, $results, $keyed = true) + public function hydrate($model, $results) { $class = get_class($model); @@ -128,17 +126,7 @@ public function hydrate($model, $results, $keyed = true) $new->original = $new->attributes; - // Typically, the resulting models are keyed by their primary key, but it - // 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; - } + $models[] = $new; } if (count($results) > 0) @@ -199,17 +187,7 @@ protected function load(&$results, $relationship, $constraints) $query->initialize($results, $relationship); - // If we're eager loading a many-to-many relationship we will disable - // 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)); - } + $query->match($relationship, $results, $query->get()); } /** diff --git a/laravel/database/eloquent/relationships/belongs_to.php b/laravel/database/eloquent/relationships/belongs_to.php index ff0d29d5..485b7fcc 100644 --- a/laravel/database/eloquent/relationships/belongs_to.php +++ b/laravel/database/eloquent/relationships/belongs_to.php @@ -87,9 +87,14 @@ public function match($relationship, &$children, $parents) 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; } } } diff --git a/laravel/database/eloquent/relationships/has_many.php b/laravel/database/eloquent/relationships/has_many.php index d14652a4..f88016d5 100644 --- a/laravel/database/eloquent/relationships/has_many.php +++ b/laravel/database/eloquent/relationships/has_many.php @@ -91,9 +91,14 @@ public function match($relationship, &$parents, $children) { $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; } } diff --git a/laravel/database/eloquent/relationships/has_many_and_belongs_to.php b/laravel/database/eloquent/relationships/has_many_and_belongs_to.php index 7a2bee1f..ad73117c 100644 --- a/laravel/database/eloquent/relationships/has_many_and_belongs_to.php +++ b/laravel/database/eloquent/relationships/has_many_and_belongs_to.php @@ -311,7 +311,7 @@ public function initialize(&$parents, $relationship) */ 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(); - // For each child we'll just get the parent that connects to the child and set the - // 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) + foreach ($parents as &$parent) { - $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; } } diff --git a/laravel/database/eloquent/relationships/has_one.php b/laravel/database/eloquent/relationships/has_one.php index 077c3ada..7addabb0 100644 --- a/laravel/database/eloquent/relationships/has_one.php +++ b/laravel/database/eloquent/relationships/has_one.php @@ -38,9 +38,14 @@ public function match($relationship, &$parents, $children) { $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; } } diff --git a/laravel/database/eloquent/relationships/has_one_or_many.php b/laravel/database/eloquent/relationships/has_one_or_many.php index 274a5f3d..a8268de6 100644 --- a/laravel/database/eloquent/relationships/has_one_or_many.php +++ b/laravel/database/eloquent/relationships/has_one_or_many.php @@ -53,7 +53,7 @@ protected function constrain() */ 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)); } } \ No newline at end of file diff --git a/laravel/database/eloquent/relationships/relationship.php b/laravel/database/eloquent/relationships/relationship.php index 2ec10aa4..34c03f6b 100644 --- a/laravel/database/eloquent/relationships/relationship.php +++ b/laravel/database/eloquent/relationships/relationship.php @@ -101,4 +101,22 @@ public function foreign_key() 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); + } + } \ No newline at end of file diff --git a/laravel/error.php b/laravel/error.php index 729f632a..bfb2fcd7 100644 --- a/laravel/error.php +++ b/laravel/error.php @@ -13,7 +13,7 @@ public static function exception($exception, $trace = true) { 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 // a simple error message and display it on the screen. We don't use a