Skip to content

Commit

Permalink
Fix morphTo eagerloading
Browse files Browse the repository at this point in the history
  • Loading branch information
RemiCollin committed Jun 19, 2018
1 parent a06ff22 commit 51546ce
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 30 deletions.
43 changes: 20 additions & 23 deletions src/Relationships/MorphTo.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Expand All @@ -90,48 +90,45 @@ 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;
}

/**
* Match the results for a given type to their parents.
*
* @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);
}

/**
Expand All @@ -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();
}

/**
Expand All @@ -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();
}

Expand Down
4 changes: 2 additions & 2 deletions src/System/Builders/ResultBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}

Expand Down
4 changes: 2 additions & 2 deletions src/System/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
}
Expand Down
10 changes: 7 additions & 3 deletions tests/cases/Relationships/MorphToTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,24 @@ 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');
$blog = $this->factoryMakeUid(Blog::class);
$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);
Expand All @@ -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);
}
Expand All @@ -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',
Expand Down

0 comments on commit 51546ce

Please sign in to comment.