Commit a1d94104 authored by Jens Segers's avatar Jens Segers

Fixed eager loading, issue #138

parent 48ac180d
...@@ -7,7 +7,6 @@ use Illuminate\Database\Eloquent\Relations\MorphMany; ...@@ -7,7 +7,6 @@ use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Eloquent\Relations\Relation;
use Jenssegers\Mongodb\Relations\BelongsTo; use Jenssegers\Mongodb\Relations\BelongsTo;
use Jenssegers\Mongodb\Relations\BelongsToMany; use Jenssegers\Mongodb\Relations\BelongsToMany;
use Jenssegers\Mongodb\Relations\EmbedsMany;
use Jenssegers\Mongodb\Query\Builder as QueryBuilder; use Jenssegers\Mongodb\Query\Builder as QueryBuilder;
abstract class Model extends \Illuminate\Database\Eloquent\Model { abstract class Model extends \Illuminate\Database\Eloquent\Model {
...@@ -221,40 +220,6 @@ abstract class Model extends \Illuminate\Database\Eloquent\Model { ...@@ -221,40 +220,6 @@ abstract class Model extends \Illuminate\Database\Eloquent\Model {
return new BelongsToMany($query, $this, $collection, $foreignKey, $otherKey, $relation); return new BelongsToMany($query, $this, $collection, $foreignKey, $otherKey, $relation);
} }
/**
* Define an embedded one-to-many relationship.
*
* @param string $related
* @param string $collection
* @return \Illuminate\Database\Eloquent\Relations\EmbedsMany
*/
protected function embedsMany($related, $localKey = null, $foreignKey = null, $relation = null)
{
if (is_null($localKey))
{
$localKey = snake_case(str_plural($related)) . '_ids';
}
if (is_null($foreignKey))
{
$foreignKey = snake_case(class_basename($this));
}
// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relatinoships.
if (is_null($relation))
{
list(, $caller) = debug_backtrace(false);
$relation = $caller['function'];
}
$query = $this->newQuery();
return new EmbedsMany($query, $this, $localKey, $foreignKey, $relation);
}
/** /**
* Get a new query builder instance for the connection. * Get a new query builder instance for the connection.
* *
......
<?php namespace Jenssegers\Mongodb; <?php namespace Jenssegers\Mongodb;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jenssegers\Mongodb\DatabaseManager as Resolver; use Jenssegers\Mongodb\DatabaseManager as Resolver;
use Jenssegers\Mongodb\Eloquent\Builder; use Jenssegers\Mongodb\Eloquent\Builder;
use Jenssegers\Mongodb\Query\Builder as QueryBuilder; use Jenssegers\Mongodb\Query\Builder as QueryBuilder;
use Jenssegers\Mongodb\Relations\BelongsTo; use Jenssegers\Mongodb\Relations\EmbedsMany;
use Jenssegers\Mongodb\Relations\BelongsToMany;
use Carbon\Carbon; use Carbon\Carbon;
use DateTime; use DateTime;
...@@ -52,6 +48,40 @@ abstract class Model extends \Jenssegers\Eloquent\Model { ...@@ -52,6 +48,40 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
if (array_key_exists($this->getKeyName(), $this->attributes)) return $this->attributes[$this->getKeyName()]; if (array_key_exists($this->getKeyName(), $this->attributes)) return $this->attributes[$this->getKeyName()];
} }
/**
* Define an embedded one-to-many relationship.
*
* @param string $related
* @param string $collection
* @return \Illuminate\Database\Eloquent\Relations\EmbedsMany
*/
protected function embedsMany($related, $localKey = null, $foreignKey = null, $relation = null)
{
if (is_null($localKey))
{
$localKey = snake_case(str_plural($related)) . '_ids';
}
if (is_null($foreignKey))
{
$foreignKey = snake_case(class_basename($this));
}
// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relatinoships.
if (is_null($relation))
{
list(, $caller) = debug_backtrace(false);
$relation = $caller['function'];
}
$query = $this->newQuery();
return new EmbedsMany($query, $this, $localKey, $foreignKey, $relation);
}
/** /**
* Convert a DateTime to a storable MongoDate object. * Convert a DateTime to a storable MongoDate object.
* *
......
...@@ -98,6 +98,18 @@ class EmbedsMany extends Relation { ...@@ -98,6 +98,18 @@ class EmbedsMany extends Relation {
*/ */
public function match(array $models, Collection $results, $relation) public function match(array $models, Collection $results, $relation)
{ {
foreach ($models as $model)
{
// Get raw attributes to skip relations and accessors.
$attributes = $model->getAttributes();
$results = isset($attributes[$this->localKey]) ? $attributes[$this->localKey] : array();
$collection = $this->toCollection($results);
$model->setRelation($relation, $collection);
}
return $models; return $models;
} }
...@@ -109,22 +121,9 @@ class EmbedsMany extends Relation { ...@@ -109,22 +121,9 @@ class EmbedsMany extends Relation {
public function getResults() public function getResults()
{ {
// Get embedded documents. // Get embedded documents.
$results = $this->getEmbedded(); $results = $this->getEmbeddedRecords();
$models = array();
// Wrap documents in model objects.
foreach ($results as $result)
{
$model = $this->related->newFromBuilder($result);
// Attatch the parent relation to the embedded model. return $this->toCollection($results);
$model->setRelation($this->foreignKey, $this->parent);
$models[] = $model;
}
return $this->related->newCollection($models);
} }
/** /**
...@@ -187,12 +186,12 @@ class EmbedsMany extends Relation { ...@@ -187,12 +186,12 @@ class EmbedsMany extends Relation {
$result = $this->query->push($this->localKey, $model->getAttributes(), true); $result = $this->query->push($this->localKey, $model->getAttributes(), true);
// Get existing embedded documents. // Get existing embedded documents.
$documents = $this->getEmbedded(); $documents = $this->getEmbeddedRecords();
// Add the document to the parent model. // Add the document to the parent model.
$documents[] = $model->getAttributes(); $documents[] = $model->getAttributes();
$this->setEmbedded($documents); $this->setEmbeddedRecords($documents);
return $result ? $model : false; return $result ? $model : false;
} }
...@@ -221,7 +220,7 @@ class EmbedsMany extends Relation { ...@@ -221,7 +220,7 @@ class EmbedsMany extends Relation {
->update(array($this->localKey . '.$' => $model->getAttributes())); ->update(array($this->localKey . '.$' => $model->getAttributes()));
// Get existing embedded documents. // Get existing embedded documents.
$documents = $this->getEmbedded(); $documents = $this->getEmbeddedRecords();
$primaryKey = $this->related->getKeyName(); $primaryKey = $this->related->getKeyName();
...@@ -237,7 +236,7 @@ class EmbedsMany extends Relation { ...@@ -237,7 +236,7 @@ class EmbedsMany extends Relation {
} }
} }
$this->setEmbedded($documents); $this->setEmbeddedRecords($documents);
return $result ? $model : false; return $result ? $model : false;
} }
...@@ -325,7 +324,7 @@ class EmbedsMany extends Relation { ...@@ -325,7 +324,7 @@ class EmbedsMany extends Relation {
} }
// Get existing embedded documents. // Get existing embedded documents.
$documents = $this->getEmbedded(); $documents = $this->getEmbeddedRecords();
// Remove the document from the parent model. // Remove the document from the parent model.
foreach ($documents as $i => $document) foreach ($documents as $i => $document)
...@@ -336,7 +335,7 @@ class EmbedsMany extends Relation { ...@@ -336,7 +335,7 @@ class EmbedsMany extends Relation {
} }
} }
$this->setEmbedded($documents); $this->setEmbeddedRecords($documents);
return $count; return $count;
} }
...@@ -364,11 +363,35 @@ class EmbedsMany extends Relation { ...@@ -364,11 +363,35 @@ class EmbedsMany extends Relation {
} }
/** /**
* Get the embedded documents array * Convert an array of embedded documents to a Collection.
*
* @param array $results
* @return Illuminate\Database\Eloquent\Collection
*/
protected function toCollection(array $results = array())
{
$models = array();
// Wrap documents in model objects.
foreach ($results as $result)
{
$model = $this->related->newFromBuilder($result);
// Attatch the parent relation to the embedded model.
$model->setRelation($this->foreignKey, $this->parent);
$models[] = $model;
}
return $this->related->newCollection($models);
}
/**
* Get the embedded documents array.
* *
* @return array * @return array
*/ */
public function getEmbedded() protected function getEmbeddedRecords()
{ {
// Get raw attributes to skip relations and accessors. // Get raw attributes to skip relations and accessors.
$attributes = $this->parent->getAttributes(); $attributes = $this->parent->getAttributes();
...@@ -377,11 +400,11 @@ class EmbedsMany extends Relation { ...@@ -377,11 +400,11 @@ class EmbedsMany extends Relation {
} }
/** /**
* Set the embedded documents array * Set the embedded documents array.
* *
* @param array $models * @param array $models
*/ */
public function setEmbedded(array $models) protected function setEmbeddedRecords(array $models)
{ {
$attributes = $this->parent->getAttributes(); $attributes = $this->parent->getAttributes();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment