diff --git a/src/Relationships/MorphTo.php b/src/Relationships/MorphTo.php index 897314f..d227b4f 100755 --- a/src/Relationships/MorphTo.php +++ b/src/Relationships/MorphTo.php @@ -76,7 +76,7 @@ protected function buildDictionary($results) { foreach ($results as $result) { if ($result[$this->morphType]) { - $this->dictionary[$result[$this->morphType]][$result[$this->foreignKey]] = $result; + $this->dictionary[$result[$this->morphType]][$result[$this->foreignKey]][] = $result; } } } @@ -90,24 +90,12 @@ protected function buildDictionary($results) * @return array */ public function match(array $results, $relation) - { - return $results; - } - - /** - * Get the results of the relationship. - * - * @throws \Analogue\ORM\Exceptions\MappingException - * - * @return EntityCollection - */ - public function getEager() { foreach (array_keys($this->dictionary) as $type) { - $this->matchToMorphParents($type, $this->getResultsByType($type)); + $results = $this->matchToMorphParents($type, $this->getResultsByType($type), $results); } - - return $this->entities; + + return $results; } /** @@ -115,23 +103,32 @@ public function getEager() * * @param string $type * @param EntityCollection $results + * @param array $parents * - * @return void + * @return array */ - protected function matchToMorphParents($type, EntityCollection $results) + protected function matchToMorphParents($type, EntityCollection $results, array $parents) { $mapper = $this->relatedMapper->getManager()->mapper($type); $keyName = $mapper->getEntityMap()->getKeyName(); + $keys = array_map(function($parent) use($keyName) { + return $parent[$keyName]; + }, $parents); + + $parents = array_combine($keys, $parents); + foreach ($results as $result) { $key = $result[$keyName]; - + if (isset($this->dictionary[$type][$key])) { - foreach ($this->dictionary[$type][$key] as $result) { - $result[$this->relation] = $result; + foreach ($this->dictionary[$type][$key] as $parent) { + $parents[$parent[$keyName]][$this->relation] = $result; } } } + + return array_values($parents); } /** @@ -151,7 +148,7 @@ protected function getResultsByType($type) $query = $mapper->getQuery(); - return $query->whereIn($key, $this->gatherKeysByType($type)->all())->get(); + return $query->whereIn($key, array_keys($this->dictionary[$type]))->get(); } /** @@ -166,7 +163,7 @@ protected function gatherKeysByType($type) $foreign = $this->foreignKey; return BaseCollection::make($this->dictionary[$type])->map(function ($entities) use ($foreign) { - return head($entities)->{$foreign}; + return head($entities)[$foreign]; })->unique(); } diff --git a/src/System/Builders/ResultBuilder.php b/src/System/Builders/ResultBuilder.php index 787469b..5cdfca6 100644 --- a/src/System/Builders/ResultBuilder.php +++ b/src/System/Builders/ResultBuilder.php @@ -120,7 +120,7 @@ protected function buildEmbeddedRelationships(array $results) : array protected function queryEagerLoadedRelationships(array $results, array $eagerLoads) : array { $this->eagerLoads = $this->parseRelations($eagerLoads); - + return $this->eagerLoadRelations($results); } @@ -196,6 +196,7 @@ public function eagerLoadRelations(array $results): array foreach ($this->eagerLoads as $name => $constraints) { // First, we'll check if the entity map has a relation and just pass if it // is not the case + if (!in_array($name, $this->entityMap->getRelationships())) { continue; } @@ -234,7 +235,6 @@ protected function loadRelation(array $results, string $name, Closure $constrain // Once we have the results, we just match those back up to their parent models // using the relationship instance. Then we just return the finished arrays // of models which have been eagerly hydrated and are readied for return. - return $relation->match($results, $name); } diff --git a/src/System/Query.php b/src/System/Query.php index f194da7..fef9f91 100755 --- a/src/System/Query.php +++ b/src/System/Query.php @@ -524,7 +524,7 @@ public function with($relations) if (is_string($relations)) { $relations = func_get_args(); } - + $this->eagerLoad = array_merge($this->eagerLoad, $relations); return $this; @@ -572,7 +572,7 @@ public function getEntities($columns = ['*']) // Run the query $results = $this->query->get($columns); - + // Pass result set to the mapper and return the EntityCollection return $this->mapper->map($results, $this->getEagerLoads()); } diff --git a/tests/cases/Relationships/MorphToTest.php b/tests/cases/Relationships/MorphToTest.php index e842c88..ce9080c 100755 --- a/tests/cases/Relationships/MorphToTest.php +++ b/tests/cases/Relationships/MorphToTest.php @@ -29,13 +29,15 @@ public function relationship_can_be_eager_loaded() $comment->commentable = $blog; $mapper = $this->mapper($comment); $mapper->store($comment); + $this->clearCache(); $loadedComment = $mapper->with('commentable')->whereId($comment->id)->first(); - + //dd($loadedComment); $this->assertInstanceOf(Blog::class, $loadedComment->commentable); $this->assertEquals($blog->id, $loadedComment->commentable->id); $this->assertNotInstanceOf(LazyLoadingInterface::class, $loadedComment->commentable); } + /** @test */ public function relationship_can_be_lazy_loaded() { $comment = new Comment('Comment 1'); @@ -43,8 +45,8 @@ public function relationship_can_be_lazy_loaded() $comment->commentable = $blog; $mapper = $this->mapper($comment); $mapper->store($comment); - $loadedComment = $mapper->with('commentable')->whereId($comment->id)->first(); - + $this->clearCache(); + $loadedComment = $mapper->whereId($comment->id)->first(); $this->assertInstanceOf(LazyLoadingInterface::class, $loadedComment->commentable); $this->assertInstanceOf(Blog::class, $loadedComment->commentable); $this->assertEquals($blog->id, $loadedComment->commentable->id); @@ -56,6 +58,7 @@ public function relation_is_set_to_null_when_foreign_key_is_null() $comment = new Comment('Comment 1'); $mapper = $this->mapper($comment); $mapper->store($comment); + $this->clearCache(); $loadedComment = $mapper->with('commentable')->whereId($comment->id)->first(); $this->assertNull($loadedComment->commentable); } @@ -69,6 +72,7 @@ public function dirty_attributes_on_related_entity_are_updated_on_store() $comment->commentable = $blog; $mapper = $this->mapper($comment); $mapper->store($comment); + $this->seeInDatabase('blogs', [ 'id' => $blog->id, 'title' => 'New Title',