Commit b9e4cdae authored by Jens Segers's avatar Jens Segers

Tweaking relations and MongoId conversion

parent 9443e8b4
...@@ -169,27 +169,23 @@ abstract class Model extends \Jenssegers\Eloquent\Model { ...@@ -169,27 +169,23 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
} }
/** /**
* Set the array of model attributes. No checking is done. * Get an attribute from the model.
* *
* @param array $attributes * @param string $key
* @param bool $sync * @return mixed
* @return void
*/ */
public function setRawAttributes(array $attributes, $sync = false) public function getAttribute($key)
{ {
foreach($attributes as $key => &$value) $attribute = parent::getAttribute($key);
// If the attribute is a MongoId object, return it as a string.
// This is makes Eloquent relations a lot easier.
if ($attribute instanceof MongoId)
{ {
/** return (string) $attribute;
* MongoIds are converted to string to make it easier to pass
* the id to other instances or relations.
*/
if ($value instanceof MongoId)
{
$value = (string) $value;
}
} }
parent::setRawAttributes($attributes, $sync); return $attribute;
} }
/** /**
...@@ -223,7 +219,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model { ...@@ -223,7 +219,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
* @param mixed $columns * @param mixed $columns
* @return int * @return int
*/ */
public function dropColumn($columns) public function drop($columns)
{ {
if (!is_array($columns)) $columns = array($columns); if (!is_array($columns)) $columns = array($columns);
...@@ -234,7 +230,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model { ...@@ -234,7 +230,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
} }
// Perform unset only on current document // Perform unset only on current document
return $query = $this->newQuery()->where($this->getKeyName(), $this->getKey())->unset($columns); return $this->newQuery()->where($this->getKeyName(), $this->getKey())->unset($columns);
} }
/** /**
...@@ -289,7 +285,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model { ...@@ -289,7 +285,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
// Unset method // Unset method
if ($method == 'unset') if ($method == 'unset')
{ {
return call_user_func_array(array($this, 'dropColumn'), $parameters); return call_user_func_array(array($this, 'drop'), $parameters);
} }
return parent::__call($method, $parameters); return parent::__call($method, $parameters);
......
...@@ -59,7 +59,7 @@ class Builder extends \Illuminate\Database\Query\Builder { ...@@ -59,7 +59,7 @@ class Builder extends \Illuminate\Database\Query\Builder {
/** /**
* Execute a query for a single record by ID. * Execute a query for a single record by ID.
* *
* @param int $id * @param mixed $id
* @param array $columns * @param array $columns
* @return mixed * @return mixed
*/ */
...@@ -377,8 +377,8 @@ class Builder extends \Illuminate\Database\Query\Builder { ...@@ -377,8 +377,8 @@ class Builder extends \Illuminate\Database\Query\Builder {
$sequence = '_id'; $sequence = '_id';
} }
// Return id as a string // Return id
return (string) $values[$sequence]; return $values[$sequence];
} }
} }
...@@ -585,7 +585,7 @@ class Builder extends \Illuminate\Database\Query\Builder { ...@@ -585,7 +585,7 @@ class Builder extends \Illuminate\Database\Query\Builder {
* @param mixed $columns * @param mixed $columns
* @return int * @return int
*/ */
public function dropColumn($columns) public function drop($columns)
{ {
if (!is_array($columns)) $columns = array($columns); if (!is_array($columns)) $columns = array($columns);
...@@ -846,7 +846,7 @@ class Builder extends \Illuminate\Database\Query\Builder { ...@@ -846,7 +846,7 @@ class Builder extends \Illuminate\Database\Query\Builder {
{ {
if ($method == 'unset') if ($method == 'unset')
{ {
return call_user_func_array(array($this, 'dropColumn'), $parameters); return call_user_func_array(array($this, 'drop'), $parameters);
} }
return parent::__call($method, $parameters); return parent::__call($method, $parameters);
......
<?php namespace Jenssegers\Mongodb\Relations; <?php namespace Jenssegers\Mongodb\Relations;
use Illuminate\Database\Eloquent\Collection;
use Jenssegers\Mongodb\Model; use Jenssegers\Mongodb\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\BelongsToMany as EloquentBelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany as EloquentBelongsToMany;
class BelongsToMany extends EloquentBelongsToMany { class BelongsToMany extends EloquentBelongsToMany {
...@@ -36,12 +36,12 @@ class BelongsToMany extends EloquentBelongsToMany { ...@@ -36,12 +36,12 @@ class BelongsToMany extends EloquentBelongsToMany {
{ {
if (static::$constraints) if (static::$constraints)
{ {
$this->query->where($this->foreignKey, $this->parent->getKey()); $this->query->where($this->getForeignKey(), '=', $this->parent->getKey());
} }
} }
/** /**
* Sync the intermediate tables with a list of IDs. * Sync the intermediate tables with a list of IDs or collection of models.
* *
* @param array $ids * @param array $ids
* @param bool $detaching * @param bool $detaching
...@@ -49,14 +49,12 @@ class BelongsToMany extends EloquentBelongsToMany { ...@@ -49,14 +49,12 @@ class BelongsToMany extends EloquentBelongsToMany {
*/ */
public function sync(array $ids, $detaching = true) public function sync(array $ids, $detaching = true)
{ {
if ($ids instanceof Collection) $ids = $ids->modelKeys();
// First we need to attach any of the associated models that are not currently // First we need to attach any of the associated models that are not currently
// in this joining table. We'll spin through the given IDs, checking to see // in this joining table. We'll spin through the given IDs, checking to see
// if they exist in the array of current ones, and if not we will insert. // if they exist in the array of current ones, and if not we will insert.
$current = $this->parent->{$this->otherKey}; $current = $this->parent->{$this->otherKey} ?: array();
// Check if the current array exists or not on the parent model and create it
// if it does not exist
if (is_null($current)) $current = array();
$records = $this->formatSyncList($ids); $records = $this->formatSyncList($ids);
...@@ -133,27 +131,6 @@ class BelongsToMany extends EloquentBelongsToMany { ...@@ -133,27 +131,6 @@ class BelongsToMany extends EloquentBelongsToMany {
if ($touch) $this->touchIfTouching(); if ($touch) $this->touchIfTouching();
} }
/**
* Create an array of records to insert into the pivot table.
*
* @param array $ids
* @return void
*/
protected function createAttachRecords($ids, array $attributes)
{
$records = array();
// To create the attachment records, we will simply spin through the IDs given
// and create a new record to insert for each ID. Each ID may actually be a
// key in the array, with extra attributes to be placed in other columns.
foreach ($ids as $key => $value)
{
$records[] = $this->attacher($key, $value, $attributes, false);
}
return $records;
}
/** /**
* Detach models from the relationship. * Detach models from the relationship.
* *
...@@ -165,6 +142,8 @@ class BelongsToMany extends EloquentBelongsToMany { ...@@ -165,6 +142,8 @@ class BelongsToMany extends EloquentBelongsToMany {
{ {
if ($ids instanceof Model) $ids = (array) $ids->getKey(); if ($ids instanceof Model) $ids = (array) $ids->getKey();
$query = $this->getNewRelatedQuery();
// If associated IDs were passed to the method we will only delete those // If associated IDs were passed to the method we will only delete those
// associations, otherwise all of the association ties will be broken. // associations, otherwise all of the association ties will be broken.
// We'll return the numbers of affected rows when we do the deletes. // We'll return the numbers of affected rows when we do the deletes.
...@@ -176,9 +155,6 @@ class BelongsToMany extends EloquentBelongsToMany { ...@@ -176,9 +155,6 @@ class BelongsToMany extends EloquentBelongsToMany {
$this->parent->pull($this->otherKey, $id); $this->parent->pull($this->otherKey, $id);
} }
// Get a new related query.
$query = $this->getNewRelatedQuery();
// Prepare the query to select all related objects. // Prepare the query to select all related objects.
if (count($ids) > 0) if (count($ids) > 0)
{ {
......
...@@ -4,7 +4,6 @@ use Illuminate\Database\Eloquent\Model; ...@@ -4,7 +4,6 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use MongoId; use MongoId;
class EmbedsMany extends Relation { class EmbedsMany extends Relation {
...@@ -120,7 +119,7 @@ class EmbedsMany extends Relation { ...@@ -120,7 +119,7 @@ class EmbedsMany extends Relation {
*/ */
public function getResults() public function getResults()
{ {
return $this->toCollection($this->getEmbeddedRecords()); return $this->get();
} }
/** /**
...@@ -130,27 +129,32 @@ class EmbedsMany extends Relation { ...@@ -130,27 +129,32 @@ class EmbedsMany extends Relation {
*/ */
public function get() public function get()
{ {
return $this->getResults(); return $this->toCollection($this->getEmbeddedRecords());
} }
/** /**
* Get the results with given ids. * Find an embedded model by its primary key.
* *
* @param array $ids * @param mixed $id
* @return \Illuminate\Database\Eloquent\Collection * @return \Illuminate\Database\Eloquent\Collection
*/ */
public function find(array $ids) public function find($id)
{ {
$documents = $this->getEmbeddedRecords(); if ($id instanceof Model)
{
$id = $id->getKey();
}
$records = $this->getEmbeddedRecords();
$primaryKey = $this->related->getKeyName(); $primaryKey = $this->related->getKeyName();
$documents = array_filter($documents, function ($document) use ($primaryKey, $ids) $record = array_first($records, function($itemKey, $record) use ($primaryKey, $id)
{ {
return in_array($document[$primaryKey], $ids); return $record[$primaryKey] == $id;
}); });
return $this->toCollection($documents); return $record ? $this->toModel($record) : null;
} }
/** /**
...@@ -165,13 +169,13 @@ class EmbedsMany extends Relation { ...@@ -165,13 +169,13 @@ class EmbedsMany extends Relation {
$this->updateTimestamps($model); $this->updateTimestamps($model);
// Insert a new document. // Attach a new model.
if ( ! $this->contains($model)) if ( ! $this->contains($model))
{ {
$result = $this->performInsert($model); $result = $this->performInsert($model);
} }
// Update an existing document. // Update an existing model.
else else
{ {
$result = $this->performUpdate($model); $result = $this->performUpdate($model);
...@@ -187,7 +191,7 @@ class EmbedsMany extends Relation { ...@@ -187,7 +191,7 @@ class EmbedsMany extends Relation {
} }
/** /**
* Get the number of embedded documents. * Get the number of embedded models.
* *
* @return int * @return int
*/ */
...@@ -197,159 +201,32 @@ class EmbedsMany extends Relation { ...@@ -197,159 +201,32 @@ class EmbedsMany extends Relation {
} }
/** /**
* Indicate if a model is already contained in the embedded documents * Check if a model is already embedded.
* *
* @param mixed $key * @param mixed $key
* @return bool * @return bool
*/ */
public function contains($key) public function contains($key)
{ {
if ($key instanceof Model) return ! is_null($this->find($key));
{
$key = $key->getKey();
}
$primaryKey = $this->related->getKeyName();
foreach ($this->getEmbeddedRecords() as $record)
{
if ($record[$primaryKey] == $key) return true;
}
return false;
} }
/** /**
* Attach a model instance to the parent model without persistence. * Associate the model instance to the given parent, without saving it to the database.
* *
* @param \Illuminate\Database\Eloquent\Model $model * @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model * @return \Illuminate\Database\Eloquent\Model
*/ */
public function associate(Model $model) public function associate(Model $model)
{ {
// Insert the related model in the parent instance
if ( ! $this->contains($model)) if ( ! $this->contains($model))
{ {
return $this->associateNew($model); return $this->associateNew($model);
} }
// Update the related model in the parent instance
else else
{ {
return $this->associateExisting($model); return $this->associateExisting($model);
} }
}
/**
* Perform a model insert operation.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model
*/
protected function performInsert(Model $model)
{
if ($this->fireModelEvent($model, 'creating') === false) return false;
// Insert the related model in the parent instance
$this->associateNew($model);
// Push the document to the database.
$result = $this->query->push($this->localKey, $model->getAttributes(), true);
if ($result)
{
$this->fireModelEvent($model, 'created', false);
return $model;
}
return false;
}
/**
* Perform a model update operation.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return Model|bool
*/
protected function performUpdate(Model $model)
{
if ($this->fireModelEvent($model, 'updating') === false) return false;
// Update the related model in the parent instance
$this->associateExisting($model);
// Get the correct foreign key value.
$id = $this->getForeignKeyValue($model->getKey());
// Update document in database.
$result = $this->query->where($this->localKey . '.' . $model->getKeyName(), $id)
->update(array($this->localKey . '.$' => $model->getAttributes()));
if ($result)
{
$this->fireModelEvent($model, 'updated', false);
return $model;
}
return false;
}
/**
* Attach a new model without persistence
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model
*/
protected function associateNew($model)
{
// Create a new key.
if ( ! $model->getAttribute('_id'))
{
$model->setAttribute('_id', new MongoId);
}
$documents = $this->getEmbeddedRecords();
// Add the document to the parent model.
$documents[] = $model->getAttributes();
$this->setEmbeddedRecords($documents);
// Mark the model as existing.
$model->exists = true;
return $model;
}
/**
* Update an existing model without persistence
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model
*/
protected function associateExisting($model)
{
// Get existing embedded documents.
$documents = $this->getEmbeddedRecords();
$primaryKey = $this->related->getKeyName();
$key = $model->getKey();
// Replace the document in the parent model.
foreach ($documents as &$document)
{
if ($document[$primaryKey] == $key)
{
$document = $model->getAttributes();
break;
}
}
$this->setEmbeddedRecords($documents);
return $model;
} }
/** /**
...@@ -406,30 +283,17 @@ class EmbedsMany extends Relation { ...@@ -406,30 +283,17 @@ class EmbedsMany extends Relation {
{ {
$ids = $this->getIdsArrayFrom($ids); $ids = $this->getIdsArrayFrom($ids);
$models = $this->find($ids); $models = $this->get()->only($ids);
$ids = array();
$primaryKey = $this->related->getKeyName();
// Pull the documents from the database. // Pull the documents from the database.
foreach ($models as $model) foreach ($models as $model)
{ {
if ($this->fireModelEvent($model, 'deleting') === false) continue; $this->performDelete($model);
$id = $model->getKey();
$this->query->pull($this->localKey, array($primaryKey => $this->getForeignKeyValue($id)));
$ids[] = $id;
$this->fireModelEvent($model, 'deleted', false);
} }
return $this->dissociate($ids);
} }
/** /**
* Dissociate the embedded models for the given IDs without persistence. * Dissociate the model instance from the given parent, without saving it to the database.
* *
* @param mixed $ids * @param mixed $ids
* @return int * @return int
...@@ -482,6 +346,147 @@ class EmbedsMany extends Relation { ...@@ -482,6 +346,147 @@ class EmbedsMany extends Relation {
return $this->save($model); return $this->save($model);
} }
/**
* Save a new model and attach it to the parent model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model
*/
protected function performInsert(Model $model)
{
if ($this->fireModelEvent($model, 'creating') === false) return false;
// Associate the new model to the parent.
$this->associateNew($model);
// Push the new model to the database.
$result = $this->query->push($this->localKey, $model->getAttributes(), true);
if ($result)
{
$this->fireModelEvent($model, 'created', false);
return $model;
}
return false;
}
/**
* Save an existing model and attach it to the parent model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return Model|bool
*/
protected function performUpdate(Model $model)
{
if ($this->fireModelEvent($model, 'updating') === false) return false;
// Update the related model in the parent instance
$this->associateExisting($model);
// Get the correct foreign key value.
$id = $this->getForeignKeyValue($model);
// Update document in database.
$result = $this->query->where($this->localKey . '.' . $model->getKeyName(), $id)
->update(array($this->localKey . '.$' => $model->getAttributes()));
if ($result)
{
$this->fireModelEvent($model, 'updated', false);
return $model;
}
return false;
}
/**
* Remove an existing model and detach it from the parent model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return bool
*/
protected function performDelete(Model $model)
{
if ($this->fireModelEvent($model, 'deleting') === false) return false;
// Get the correct foreign key value.
$id = $this->getForeignKeyValue($model);
$result = $this->query->pull($this->localKey, array($model->getKeyName() => $id));
if ($result)
{
$this->fireModelEvent($model, 'deleted', false);
// Update the related model in the parent instance
$this->dissociate($model);
return true;
}
return false;
}
/**
* Associate a new model instance to the given parent, without saving it to the database.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model
*/
protected function associateNew($model)
{
// Create a new key.
if ( ! $model->getAttribute('_id'))
{
$model->setAttribute('_id', new MongoId);
}
$documents = $this->getEmbeddedRecords();
// Add the document to the parent model.
$documents[] = $model->getAttributes();
$this->setEmbeddedRecords($documents);
// Mark the model as existing.
$model->exists = true;
return $model;
}
/**
* Associate an existing model instance to the given parent, without saving it to the database.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model
*/
protected function associateExisting($model)
{
// Get existing embedded documents.
$documents = $this->getEmbeddedRecords();
$primaryKey = $this->related->getKeyName();
$key = $model->getKey();
// Replace the document in the parent model.
foreach ($documents as &$document)
{
if ($document[$primaryKey] == $key)
{
$document = $model->getAttributes();
break;
}
}
$this->setEmbeddedRecords($documents);
return $model;
}
/** /**
* Transform single ID, single Model or array of Models into an array of IDs * Transform single ID, single Model or array of Models into an array of IDs
* *
...@@ -500,29 +505,37 @@ class EmbedsMany extends Relation { ...@@ -500,29 +505,37 @@ class EmbedsMany extends Relation {
return $ids; return $ids;
} }
/**
* Create a related model instanced.
*
* @param array $attributes [description]
* @return [type] [description]
*/
protected function toModel(array $attributes)
{
$model = $this->related->newFromBuilder($attributes);
// Attatch the parent relation to the embedded model.
$model->setRelation($this->foreignKey, $this->parent);
$model->setHidden(array_merge($model->getHidden(), array($this->foreignKey)));
return $model;
}
/** /**
* Convert an array of embedded documents to a Collection. * Convert an array of embedded documents to a Collection.
* *
* @param array $results * @param array $records
* @return Illuminate\Database\Eloquent\Collection * @return Illuminate\Database\Eloquent\Collection
*/ */
protected function toCollection(array $results = array()) protected function toCollection(array $records = array())
{ {
$models = array(); $models = array();
// Wrap documents in model objects. // Wrap records in model objects.
foreach ($results as $model) foreach ($records as $attributes)
{ {
if ( ! $model instanceof Model) $models[] = $this->toModel($attributes);
{
$model = $this->related->newFromBuilder($model);
}
// Attatch the parent relation to the embedded model.
$model->setRelation($this->foreignKey, $this->parent);
$model->setHidden(array_merge($model->getHidden(), array($this->foreignKey)));
$models[] = $model;
} }
if (count($models) > 0) if (count($models) > 0)
...@@ -534,7 +547,7 @@ class EmbedsMany extends Relation { ...@@ -534,7 +547,7 @@ class EmbedsMany extends Relation {
} }
/** /**
* Get the embedded documents array. * Get the embedded records array.
* *
* @return array * @return array
*/ */
...@@ -552,7 +565,7 @@ class EmbedsMany extends Relation { ...@@ -552,7 +565,7 @@ class EmbedsMany extends Relation {
} }
/** /**
* Set the embedded documents array. * Set the embedded records array.
* *
* @param array $models * @param array $models
* @return void * @return void
...@@ -598,6 +611,11 @@ class EmbedsMany extends Relation { ...@@ -598,6 +611,11 @@ class EmbedsMany extends Relation {
*/ */
protected function getForeignKeyValue($id) protected function getForeignKeyValue($id)
{ {
if ($id instanceof Model)
{
$id = $id->getKey();
}
// Convert the id to MongoId if necessary. // Convert the id to MongoId if necessary.
return $this->getBaseQuery()->convertKey($id); return $this->getBaseQuery()->convertKey($id);
} }
......
<?php namespace Jenssegers\Mongodb\Relations; <?php namespace Jenssegers\Mongodb\Relations;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Collection as BaseCollection; use Illuminate\Database\Eloquent\Relations\MorphTo as EloquentMorphTo;
class MorphTo extends BelongsTo { class MorphTo extends EloquentMorphTo {
/** /**
* The type of the polymorphic relation. * Set the base constraints on the relation query.
* *
* @var string * @return void
*/ */
protected $morphType; public function addConstraints()
/**
* The models whose relations are being eager loaded.
*
* @var \Illuminate\Database\Eloquent\Collection
*/
protected $models;
/**
* All of the models keyed by ID.
*
* @var array
*/
protected $dictionary = array();
/**
* Create a new belongs to relationship instance.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $foreignKey
* @param string $otherKey
* @param string $type
* @param string $relation
* @return void
*/
public function __construct(Builder $query, Model $parent, $foreignKey, $otherKey, $type, $relation)
{ {
$this->morphType = $type; if (static::$constraints)
{
parent::__construct($query, $parent, $foreignKey, $otherKey, $relation); // For belongs to relationships, which are essentially the inverse of has one
// or has many relationships, we need to actually query on the primary key
// of the related models matching on the foreign key that's on a parent.
$this->query->where($this->otherKey, '=', $this->parent->{$this->foreignKey});
}
} }
/** /**
...@@ -58,125 +32,4 @@ class MorphTo extends BelongsTo { ...@@ -58,125 +32,4 @@ class MorphTo extends BelongsTo {
$this->buildDictionary($this->models = Collection::make($models)); $this->buildDictionary($this->models = Collection::make($models));
} }
/**
* Buiild a dictionary with the models.
*
* @param \Illuminate\Database\Eloquent\Models $models
* @return void
*/
protected function buildDictionary(Collection $models)
{
foreach ($models as $model)
{
if ($model->{$this->morphType})
{
$this->dictionary[$model->{$this->morphType}][$model->{$this->foreignKey}][] = $model;
}
}
}
/**
* Match the eagerly loaded results to their parents.
*
* @param array $models
* @param \Illuminate\Database\Eloquent\Collection $results
* @param string $relation
* @return array
*/
public function match(array $models, Collection $results, $relation)
{
return $models;
}
/**
* Get the results of the relationship.
*
* Called via eager load method of Eloquent query builder.
*
* @return mixed
*/
public function getEager()
{
foreach (array_keys($this->dictionary) as $type)
{
$this->matchToMorphParents($type, $this->getResultsByType($type));
}
return $this->models;
}
/**
* Match the results for a given type to their parents.
*
* @param string $type
* @param \Illuminate\Database\Eloquent\Collection $results
* @return void
*/
protected function matchToMorphParents($type, Collection $results)
{
foreach ($results as $result)
{
if (isset($this->dictionary[$type][$result->getKey()]))
{
foreach ($this->dictionary[$type][$result->getKey()] as $model)
{
$model->setRelation($this->relation, $result);
}
}
}
}
/**
* Get all of the relation results for a type.
*
* @param string $type
* @return \Illuminate\Database\Eloquent\Collection
*/
protected function getResultsByType($type)
{
$instance = $this->createModelByType($type);
$key = $instance->getKeyName();
return $instance->whereIn($key, $this->gatherKeysByType($type)->all())->get();
}
/**
* Gather all of the foreign keys for a given type.
*
* @param string $type
* @return array
*/
protected function gatherKeysByType($type)
{
$foreign = $this->foreignKey;
return BaseCollection::make($this->dictionary[$type])->map(function($models) use ($foreign)
{
return head($models)->{$foreign};
})->unique();
}
/**
* Create a new model instance by type.
*
* @param string $type
* @return \Illuminate\Database\Eloquent\Model
*/
public function createModelByType($type)
{
return new $type;
}
/**
* Get the dictionary used by the relationship.
*
* @return array
*/
public function getDictionary()
{
return $this->dictionary;
}
} }
...@@ -34,10 +34,14 @@ class ModelTest extends TestCase { ...@@ -34,10 +34,14 @@ class ModelTest extends TestCase {
$this->assertEquals(1, User::count()); $this->assertEquals(1, User::count());
$this->assertTrue(isset($user->_id)); $this->assertTrue(isset($user->_id));
$this->assertTrue(is_string($user->_id));
$this->assertNotEquals('', (string) $user->_id); $this->assertNotEquals('', (string) $user->_id);
$this->assertNotEquals(0, strlen((string) $user->_id)); $this->assertNotEquals(0, strlen((string) $user->_id));
$this->assertInstanceOf('Carbon\Carbon', $user->created_at); $this->assertInstanceOf('Carbon\Carbon', $user->created_at);
$raw = $user->getAttributes();
$this->assertInstanceOf('MongoId', $raw['_id']);
$this->assertEquals('John Doe', $user->name); $this->assertEquals('John Doe', $user->name);
$this->assertEquals(35, $user->age); $this->assertEquals(35, $user->age);
} }
...@@ -50,6 +54,9 @@ class ModelTest extends TestCase { ...@@ -50,6 +54,9 @@ class ModelTest extends TestCase {
$user->age = 35; $user->age = 35;
$user->save(); $user->save();
$raw = $user->getAttributes();
$this->assertInstanceOf('MongoId', $raw['_id']);
$check = User::find($user->_id); $check = User::find($user->_id);
$check->age = 36; $check->age = 36;
...@@ -65,6 +72,9 @@ class ModelTest extends TestCase { ...@@ -65,6 +72,9 @@ class ModelTest extends TestCase {
$user->update(array('age' => 20)); $user->update(array('age' => 20));
$raw = $user->getAttributes();
$this->assertInstanceOf('MongoId', $raw['_id']);
$check = User::find($user->_id); $check = User::find($user->_id);
$this->assertEquals(20, $check->age); $this->assertEquals(20, $check->age);
} }
......
...@@ -54,9 +54,7 @@ class QueryBuilderTest extends TestCase { ...@@ -54,9 +54,7 @@ class QueryBuilderTest extends TestCase {
public function testInsertGetId() public function testInsertGetId()
{ {
$id = DB::collection('users')->insertGetId(array('name' => 'John Doe')); $id = DB::collection('users')->insertGetId(array('name' => 'John Doe'));
$this->assertInstanceOf('MongoId', $id);
$this->assertTrue(is_string($id));
$this->assertEquals(24, strlen($id));
} }
public function testBatchInsert() public function testBatchInsert()
......
...@@ -308,6 +308,10 @@ class RelationsTest extends TestCase { ...@@ -308,6 +308,10 @@ class RelationsTest extends TestCase {
$this->assertInstanceOf('DateTime', $address->created_at); $this->assertInstanceOf('DateTime', $address->created_at);
$this->assertInstanceOf('DateTime', $address->updated_at); $this->assertInstanceOf('DateTime', $address->updated_at);
$this->assertNotNull($address->_id); $this->assertNotNull($address->_id);
$this->assertTrue(is_string($address->_id));
$raw = $address->getAttributes();
$this->assertInstanceOf('MongoId', $raw['_id']);
$address = $user->addresses()->save(new Address(array('city' => 'Paris'))); $address = $user->addresses()->save(new Address(array('city' => 'Paris')));
...@@ -410,15 +414,21 @@ class RelationsTest extends TestCase { ...@@ -410,15 +414,21 @@ class RelationsTest extends TestCase {
$user = User::create(array()); $user = User::create(array());
$address = $user->addresses()->create(array('city' => 'Bruxelles')); $address = $user->addresses()->create(array('city' => 'Bruxelles'));
$this->assertInstanceOf('Address', $address); $this->assertInstanceOf('Address', $address);
$this->assertInstanceOf('MongoID', $address->_id); $this->assertTrue(is_string($address->_id));
$this->assertEquals(array('Bruxelles'), $user->addresses->lists('city')); $this->assertEquals(array('Bruxelles'), $user->addresses->lists('city'));
$raw = $address->getAttributes();
$this->assertInstanceOf('MongoId', $raw['_id']);
$freshUser = User::find($user->id); $freshUser = User::find($user->id);
$this->assertEquals(array('Bruxelles'), $freshUser->addresses->lists('city')); $this->assertEquals(array('Bruxelles'), $freshUser->addresses->lists('city'));
$user = User::create(array()); $user = User::create(array());
$address = $user->addresses()->create(array('_id' => '', 'city' => 'Bruxelles')); $address = $user->addresses()->create(array('_id' => '', 'city' => 'Bruxelles'));
$this->assertInstanceOf('MongoID', $address->_id); $this->assertTrue(is_string($address->_id));
$raw = $address->getAttributes();
$this->assertInstanceOf('MongoId', $raw['_id']);
} }
public function testEmbedsManyCreateMany() public function testEmbedsManyCreateMany()
...@@ -553,4 +563,20 @@ class RelationsTest extends TestCase { ...@@ -553,4 +563,20 @@ class RelationsTest extends TestCase {
$address->unsetEventDispatcher(); $address->unsetEventDispatcher();
} }
public function testEmbedsManyFindOrContains()
{
$user = User::create(array('name' => 'John Doe'));
$address1 = $user->addresses()->save(new Address(array('city' => 'New York')));
$address2 = $user->addresses()->save(new Address(array('city' => 'Paris')));
$address = $user->addresses()->find($address1->_id);
$this->assertEquals($address->city, $address1->city);
$address = $user->addresses()->find($address2->_id);
$this->assertEquals($address->city, $address2->city);
$this->assertTrue($user->addresses()->contains($address2->_id));
$this->assertFalse($user->addresses()->contains('123'));
}
} }
...@@ -32,6 +32,9 @@ class TestCase extends Orchestra\Testbench\TestCase { ...@@ -32,6 +32,9 @@ class TestCase extends Orchestra\Testbench\TestCase {
// overwrite database configuration // overwrite database configuration
$app['config']->set('database.connections.mysql', $config['connections']['mysql']); $app['config']->set('database.connections.mysql', $config['connections']['mysql']);
$app['config']->set('database.connections.mongodb', $config['connections']['mongodb']); $app['config']->set('database.connections.mongodb', $config['connections']['mongodb']);
// overwrite cache configuration
$app['config']->set('cache.driver', 'array');
} }
} }
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