Commit 21a32bf2 authored by Jens Segers's avatar Jens Segers

Improve saving embedded models

parent d2c1da3a
...@@ -16,6 +16,86 @@ class Builder extends EloquentBuilder { ...@@ -16,6 +16,86 @@ class Builder extends EloquentBuilder {
'count', 'min', 'max', 'avg', 'sum', 'exists', 'push', 'pull' 'count', 'min', 'max', 'avg', 'sum', 'exists', 'push', 'pull'
); );
/**
* Update a record in the database.
*
* @param array $values
* @return int
*/
public function update(array $values)
{
// Intercept operations on embedded models and delegate logic
// to the parent relation instance.
if ($relation = $this->model->getParent())
{
$relation->performUpdate($this->model, $values);
return 1;
}
return parent::update($values);
}
/**
* Insert a new record into the database.
*
* @param array $values
* @return bool
*/
public function insert(array $values)
{
// Intercept operations on embedded models and delegate logic
// to the parent relation instance.
if ($relation = $this->model->getParent())
{
$relation->performInsert($this->model, $values);
return true;
}
return parent::insert($values);
}
/**
* Insert a new record and get the value of the primary key.
*
* @param array $values
* @param string $sequence
* @return int
*/
public function insertGetId(array $values, $sequence = null)
{
// Intercept operations on embedded models and delegate logic
// to the parent relation instance.
if ($relation = $this->model->getParent())
{
$relation->performInsert($this->model, $values);
return $this->model->getKey();
}
return parent::insertGetId($values, $sequence);
}
/**
* Delete a record from the database.
*
* @return mixed
*/
public function delete()
{
// Intercept operations on embedded models and delegate logic
// to the parent relation instance.
if ($relation = $this->model->getParent())
{
$relation->performDelete($this->model);
return $this->model->getKey();
}
return parent::delete();
}
/** /**
* Add the "has" condition where clause to the query. * Add the "has" condition where clause to the query.
* *
......
...@@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Collection; ...@@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Collection;
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 Illuminate\Database\Eloquent\Relations\Relation;
use Jenssegers\Mongodb\Relations\EmbedsOneOrMany; use Jenssegers\Mongodb\Relations\EmbedsOneOrMany;
use Jenssegers\Mongodb\Relations\EmbedsMany; use Jenssegers\Mongodb\Relations\EmbedsMany;
use Jenssegers\Mongodb\Relations\EmbedsOne; use Jenssegers\Mongodb\Relations\EmbedsOne;
...@@ -29,6 +30,13 @@ abstract class Model extends \Jenssegers\Eloquent\Model { ...@@ -29,6 +30,13 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
*/ */
protected $primaryKey = '_id'; protected $primaryKey = '_id';
/**
* The parent relation instance.
*
* @var Relation
*/
protected $parent;
/** /**
* The connection resolver instance. * The connection resolver instance.
* *
...@@ -290,6 +298,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model { ...@@ -290,6 +298,7 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
if ($key == '_id' and is_string($value)) if ($key == '_id' and is_string($value))
{ {
$builder = $this->newBaseQueryBuilder(); $builder = $this->newBaseQueryBuilder();
$value = $builder->convertKey($value); $value = $builder->convertKey($value);
} }
...@@ -369,6 +378,26 @@ abstract class Model extends \Jenssegers\Eloquent\Model { ...@@ -369,6 +378,26 @@ abstract class Model extends \Jenssegers\Eloquent\Model {
return call_user_func_array(array($query, 'pull'), func_get_args()); return call_user_func_array(array($query, 'pull'), func_get_args());
} }
/**
* Set the parent relation.
*
* @param Relation $relation
*/
public function setParent(Relation $relation)
{
$this->parent = $relation;
}
/**
* Get the parent relation.
*
* @return Relation
*/
public function getParent()
{
return $this->parent;
}
/** /**
* Create a new Eloquent query builder for the model. * Create a new Eloquent query builder for the model.
* *
......
...@@ -19,54 +19,82 @@ class EmbedsMany extends EmbedsOneOrMany { ...@@ -19,54 +19,82 @@ class EmbedsMany extends EmbedsOneOrMany {
} }
/** /**
* Simulate order by method. * Save a new model and attach it to the parent model.
* *
* @param string $column * @param \Illuminate\Database\Eloquent\Model $model
* @param string $direction * @return \Illuminate\Database\Eloquent\Model
* @return Illuminate\Database\Eloquent\Collection
*/ */
public function orderBy($column, $direction = 'asc') public function performInsert(Model $model, array $values)
{ {
$descending = strtolower($direction) == 'desc'; // Generate a new key if needed.
if ($model->getKeyName() == '_id' and ! $model->getKey())
{
$model->setAttribute('_id', new MongoId);
}
return $this->getResults()->sortBy($column, SORT_REGULAR, $descending); // Push the new model to the database.
$result = $this->query->push($this->localKey, $model->getAttributes(), true);
// Attach the model to its parent.
if ($result) $this->associate($model);
return $result ? $model : false;
} }
/** /**
* Associate the model instance to the given parent, without saving it to the database. * Save an existing model and attach it to the parent model.
* *
* @param \Illuminate\Database\Eloquent\Model $model * @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model * @return Model|bool
*/ */
public function associate(Model $model) public function performUpdate(Model $model, array $values)
{
if ( ! $this->contains($model))
{
return $this->associateNew($model);
}
else
{ {
return $this->associateExisting($model); // Get the correct foreign key value.
} $foreignKey = $this->getForeignKeyValue($model);
// Update document in database.
$result = $this->query->where($this->localKey . '.' . $model->getKeyName(), $foreignKey)
->update(array($this->localKey . '.$' => $model->getAttributes()));
// Attach the model to its parent.
if ($result) $this->associate($model);
return $result ? $model : false;
} }
/** /**
* Destroy the embedded models for the given IDs. * Delete an existing model and detach it from the parent model.
* *
* @param mixed $ids * @param Model $model
* @return int * @return int
*/ */
public function destroy($ids = array()) public function performDelete(Model $model)
{ {
$ids = $this->getIdsArrayFrom($ids); // Get the correct foreign key value.
$foreignKey = $this->getForeignKeyValue($model);
// Get all models matching the given ids. $result = $this->query->pull($this->localKey, array($model->getKeyName() => $foreignKey));
$models = $this->get()->only($ids);
// Pull the documents from the database. if ($result) $this->dissociate($model);
foreach ($models as $model)
return $result;
}
/**
* Associate the model instance to the given parent, without saving it to the database.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model
*/
public function associate(Model $model)
{
if ( ! $this->contains($model))
{
return $this->associateNew($model);
}
else
{ {
$this->performDelete($model); return $this->associateExisting($model);
} }
} }
...@@ -81,6 +109,7 @@ class EmbedsMany extends EmbedsOneOrMany { ...@@ -81,6 +109,7 @@ class EmbedsMany extends EmbedsOneOrMany {
$ids = $this->getIdsArrayFrom($ids); $ids = $this->getIdsArrayFrom($ids);
$records = $this->getEmbedded(); $records = $this->getEmbedded();
$primaryKey = $this->related->getKeyName(); $primaryKey = $this->related->getKeyName();
// Remove the document from the parent model. // Remove the document from the parent model.
...@@ -101,27 +130,41 @@ class EmbedsMany extends EmbedsOneOrMany { ...@@ -101,27 +130,41 @@ class EmbedsMany extends EmbedsOneOrMany {
} }
/** /**
* Delete all embedded models. * Destroy the embedded models for the given IDs.
* *
* @param mixed $ids
* @return int * @return int
*/ */
public function delete() public function destroy($ids = array())
{ {
// Overwrite the local key with an empty array. $count = 0;
$result = $this->query->update(array($this->localKey => array()));
// If the update query was successful, we will remove the embedded records $ids = $this->getIdsArrayFrom($ids);
// of the parent instance.
if ($result) // Get all models matching the given ids.
{ $models = $this->getResults()->only($ids);
$count = $this->count();
$this->setEmbedded(array()); // Pull the documents from the database.
foreach ($models as $model)
{
if ($model->delete()) $count++;
}
// Return the number of deleted embedded records.
return $count; return $count;
} }
/**
* Delete all embedded models.
*
* @return int
*/
public function delete()
{
// Overwrite the local key with an empty array.
$result = $this->query->update(array($this->localKey => array()));
if ($result) $this->setEmbedded(array());
return $result; return $result;
} }
...@@ -147,78 +190,6 @@ class EmbedsMany extends EmbedsOneOrMany { ...@@ -147,78 +190,6 @@ class EmbedsMany extends EmbedsOneOrMany {
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)
{
// Create a new key if needed.
if ( ! $model->getAttribute('_id'))
{
$model->setAttribute('_id', new MongoId);
}
// Push the new model to the database.
$result = $this->query->push($this->localKey, $model->getAttributes(), true);
// Associate the new model to the parent.
if ($result) $this->associateNew($model);
return $result ? $model : 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)
{
// 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()));
// Update the related model in the parent instance
if ($result) $this->associateExisting($model);
return $result ? $model : 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. * Associate a new model instance to the given parent, without saving it to the database.
* *
...@@ -235,12 +206,10 @@ class EmbedsMany extends EmbedsOneOrMany { ...@@ -235,12 +206,10 @@ class EmbedsMany extends EmbedsOneOrMany {
$records = $this->getEmbedded(); $records = $this->getEmbedded();
// Add the document to the parent model. // Add the new model to the embedded documents.
$records[] = $model->getAttributes(); $records[] = $model->getAttributes();
$this->setEmbedded($records); return $this->setEmbedded($records);
return $model;
} }
/** /**
...@@ -255,6 +224,7 @@ class EmbedsMany extends EmbedsOneOrMany { ...@@ -255,6 +224,7 @@ class EmbedsMany extends EmbedsOneOrMany {
$records = $this->getEmbedded(); $records = $this->getEmbedded();
$primaryKey = $this->related->getKeyName(); $primaryKey = $this->related->getKeyName();
$key = $model->getKey(); $key = $model->getKey();
// Replace the document in the parent model. // Replace the document in the parent model.
...@@ -267,9 +237,7 @@ class EmbedsMany extends EmbedsOneOrMany { ...@@ -267,9 +237,7 @@ class EmbedsMany extends EmbedsOneOrMany {
} }
} }
$this->setEmbedded($records); return $this->setEmbedded($records);
return $model;
} }
/** /**
...@@ -290,11 +258,25 @@ class EmbedsMany extends EmbedsOneOrMany { ...@@ -290,11 +258,25 @@ class EmbedsMany extends EmbedsOneOrMany {
*/ */
protected function setEmbedded($models) protected function setEmbedded($models)
{ {
if (! is_array($models)) $models = array($models); if ( ! is_array($models)) $models = array($models);
return parent::setEmbedded(array_values($models)); return parent::setEmbedded(array_values($models));
} }
/**
* Simulate order by method.
*
* @param string $column
* @param string $direction
* @return Illuminate\Database\Eloquent\Collection
*/
public function orderBy($column, $direction = 'asc')
{
$descending = strtolower($direction) == 'desc';
return $this->getResults()->sortBy($column, SORT_REGULAR, $descending);
}
/** /**
* Handle dynamic method calls to the relationship. * Handle dynamic method calls to the relationship.
* *
......
...@@ -19,75 +19,79 @@ class EmbedsOne extends EmbedsOneOrMany { ...@@ -19,75 +19,79 @@ class EmbedsOne extends EmbedsOneOrMany {
} }
/** /**
* Check if a model is already embedded. * Save a new model and attach it to the parent model.
* *
* @param mixed $key * @param \Illuminate\Database\Eloquent\Model $model
* @return bool * @return \Illuminate\Database\Eloquent\Model
*/ */
public function contains($key) public function performInsert(Model $model, array $values)
{ {
if ($key instanceof Model) $key = $key->getKey(); // Generate a new key if needed.
if ($model->getKeyName() == '_id' and ! $model->getKey())
{
$model->setAttribute('_id', new MongoId);
}
$embedded = $this->getEmbedded(); $result = $this->query->update(array($this->localKey => $model->getAttributes()));
$primaryKey = $this->related->getKeyName(); // Attach the model to its parent.
if ($result) $this->associate($model);
return ($embedded and $embedded[$primaryKey] == $key); return $result ? $model : false;
} }
/** /**
* Associate the model instance to the given parent, without saving it to the database. * Save an existing model and attach it to the parent model.
* *
* @param \Illuminate\Database\Eloquent\Model $model * @param \Illuminate\Database\Eloquent\Model $model
* @return \Illuminate\Database\Eloquent\Model * @return Model|bool
*/ */
public function associate(Model $model) public function performUpdate(Model $model, array $values)
{ {
// Create a new key if needed. $result = $this->query->update(array($this->localKey => $model->getAttributes()));
if ( ! $model->getAttribute('_id'))
{
$model->setAttribute('_id', new MongoId);
}
$this->setEmbedded($model->getAttributes()); // Attach the model to its parent.
if ($result) $this->associate($model);
return $model; return $result ? $model : false;
} }
/** /**
* Save a new model and attach it to the parent model. * Delete an existing model and detach it from the parent model.
* *
* @param \Illuminate\Database\Eloquent\Model $model * @param Model $model
* @return \Illuminate\Database\Eloquent\Model * @return int
*/ */
protected function performInsert(Model $model) public function performDelete(Model $model)
{
// Create a new key if needed.
if ( ! $model->getAttribute('_id'))
{ {
$model->setAttribute('_id', new MongoId); // Overwrite the local key with an empty array.
} $result = $this->query->update(array($this->localKey => null));
$result = $this->query->update(array($this->localKey => $model->getAttributes()));
if ($result) $this->associate($model); // Detach the model from its parent.
if ($result) $this->dissociate();
return $result ? $model : false; return $result;
} }
/** /**
* Save an existing model and attach it to the parent model. * Attach the model to its parent.
* *
* @param \Illuminate\Database\Eloquent\Model $model * @param \Illuminate\Database\Eloquent\Model $model
* @return Model|bool * @return \Illuminate\Database\Eloquent\Model
*/ */
protected function performUpdate(Model $model) public function associate(Model $model)
{ {
$result = $this->query->update(array($this->localKey => $model->getAttributes())); return $this->setEmbedded($model->getAttributes());
}
if ($result) $this->associate($model);
return $result ? $model : false; /**
* Detach the model from its parent.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function dissociate()
{
return $this->setEmbedded(null);
} }
/** /**
...@@ -97,22 +101,26 @@ class EmbedsOne extends EmbedsOneOrMany { ...@@ -97,22 +101,26 @@ class EmbedsOne extends EmbedsOneOrMany {
*/ */
public function delete() public function delete()
{ {
// Overwrite the local key with an empty array. $model = $this->getResults();
$result = $this->query->update(array($this->localKey => null));
return $this->performDelete($model);
}
// If the update query was successful, we will remove the embedded records /**
// of the parent instance. * Check if a model is already embedded.
if ($result) *
* @param mixed $key
* @return bool
*/
public function contains($key)
{ {
$count = $this->count(); if ($key instanceof Model) $key = $key->getKey();
$this->setEmbedded(null); $embedded = $this->getEmbedded();
// Return the number of deleted embedded records. $primaryKey = $this->related->getKeyName();
return $count;
}
return $result; return ($embedded and $embedded[$primaryKey] == $key);
} }
} }
...@@ -86,6 +86,8 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -86,6 +86,8 @@ abstract class EmbedsOneOrMany extends Relation {
{ {
foreach ($models as $model) foreach ($models as $model)
{ {
$model->setParent($this);
$model->setRelation($relation, $this->related->newCollection()); $model->setRelation($relation, $this->related->newCollection());
} }
...@@ -106,6 +108,8 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -106,6 +108,8 @@ abstract class EmbedsOneOrMany extends Relation {
{ {
$results = $model->$relation()->getResults(); $results = $model->$relation()->getResults();
$model->setParent($this);
$model->setRelation($relation, $results); $model->setRelation($relation, $results);
} }
...@@ -140,44 +144,22 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -140,44 +144,22 @@ abstract class EmbedsOneOrMany extends Relation {
*/ */
public function save(Model $model) public function save(Model $model)
{ {
if ($this->fireModelEvent($model, 'saving') === false) return false; $model->setParent($this);
$this->updateTimestamps($model);
// Attach a new model.
if ( ! $this->contains($model))
{
if ($this->fireModelEvent($model, 'creating') === false) return false;
$result = $this->performInsert($model);
if ($result)
{
$this->fireModelEvent($model, 'created', false);
// Mark model as existing
$model->exists = true;
}
}
// Update an existing model.
else
{
if ($this->fireModelEvent($model, 'updating') === false) return false;
$result = $this->performUpdate($model);
if ($result) $this->fireModelEvent($model, 'updated', false); return $model->save() ? $model : false;
} }
if ($result) /**
* Attach an array of models to the parent instance.
*
* @param array $models
* @return array
*/
public function saveMany(array $models)
{ {
$this->fireModelEvent($result, 'saved', false); array_walk($models, array($this, 'save'));
return $result;
}
return false; return $models;
} }
/** /**
...@@ -191,24 +173,13 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -191,24 +173,13 @@ abstract class EmbedsOneOrMany extends Relation {
// Here we will set the raw attributes to avoid hitting the "fill" method so // Here we will set the raw attributes to avoid hitting the "fill" method so
// that we do not have to worry about a mass accessor rules blocking sets // that we do not have to worry about a mass accessor rules blocking sets
// on the models. Otherwise, some of these attributes will not get set. // on the models. Otherwise, some of these attributes will not get set.
$instance = $this->related->newInstance(); $instance = $this->related->newInstance($attributes);
$instance->setRawAttributes($attributes); $instance->setParent($this);
return $this->save($instance); $instance->save();
}
/** return $instance;
* Attach an array of models to the parent instance.
*
* @param array $models
* @return array
*/
public function saveMany(array $models)
{
array_walk($models, array($this, 'save'));
return $models;
} }
/** /**
...@@ -219,7 +190,12 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -219,7 +190,12 @@ abstract class EmbedsOneOrMany extends Relation {
*/ */
public function createMany(array $records) public function createMany(array $records)
{ {
$instances = array_map(array($this, 'create'), $records); $instances = array();
foreach ($records as $record)
{
$instances[] = $this->create($record);
}
return $instances; return $instances;
} }
...@@ -232,7 +208,7 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -232,7 +208,7 @@ abstract class EmbedsOneOrMany extends Relation {
*/ */
protected function getIdsArrayFrom($ids) protected function getIdsArrayFrom($ids)
{ {
if (! is_array($ids)) $ids = array($ids); if ( ! is_array($ids)) $ids = array($ids);
foreach ($ids as &$id) foreach ($ids as &$id)
{ {
...@@ -242,26 +218,6 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -242,26 +218,6 @@ abstract class EmbedsOneOrMany extends Relation {
return $ids; return $ids;
} }
/**
* Create a related model instanced.
*
* @param array $attributes [description]
* @return [type] [description]
*/
protected function toModel($attributes = array())
{
if (is_null($attributes)) return null;
$model = $this->related->newFromBuilder((array) $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;
}
/** /**
* Get the embedded records array. * Get the embedded records array.
* *
...@@ -278,43 +234,20 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -278,43 +234,20 @@ abstract class EmbedsOneOrMany extends Relation {
/** /**
* Set the embedded records array. * Set the embedded records array.
* *
* @param array $models * @param array $records
* @return void * @return \Illuminate\Database\Eloquent\Model
*/ */
protected function setEmbedded($data) protected function setEmbedded($records)
{ {
$attributes = $this->parent->getAttributes(); $attributes = $this->parent->getAttributes();
$attributes[$this->localKey] = $data; $attributes[$this->localKey] = $records;
// Set raw attributes to skip mutators. // Set raw attributes to skip mutators.
$this->parent->setRawAttributes($attributes); $this->parent->setRawAttributes($attributes);
// Set the relation on the parent. // Set the relation on the parent.
$this->parent->setRelation($this->relation, $this->getResults()); return $this->parent->setRelation($this->relation, $this->getResults());
}
/**
* Update the creation and update timestamps.
*
* @return void
*/
protected function updateTimestamps(Model $model)
{
// Check if this model uses timestamps first.
if ( ! $model->timestamps) return;
$time = $model->freshTimestamp();
if ( ! $model->isDirty(Model::UPDATED_AT))
{
$model->setUpdatedAt($time);
}
if ( ! $model->exists && ! $model->isDirty(Model::CREATED_AT))
{
$model->setCreatedAt($time);
}
} }
/** /**
...@@ -344,7 +277,6 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -344,7 +277,6 @@ abstract class EmbedsOneOrMany extends Relation {
{ {
$models = array(); $models = array();
// Wrap records in model objects.
foreach ($records as $attributes) foreach ($records as $attributes)
{ {
$models[] = $this->toModel($attributes); $models[] = $this->toModel($attributes);
...@@ -359,26 +291,25 @@ abstract class EmbedsOneOrMany extends Relation { ...@@ -359,26 +291,25 @@ abstract class EmbedsOneOrMany extends Relation {
} }
/** /**
* Fire the given event for the given model. * Create a related model instanced.
* *
* @param string $event * @param array $attributes
* @param bool $halt * @return \Illuminate\Database\Eloquent\Model
* @return mixed
*/ */
protected function fireModelEvent(Model $model, $event, $halt = true) protected function toModel($attributes = array())
{ {
$dispatcher = $model->getEventDispatcher(); if (is_null($attributes)) return null;
if ( is_null($dispatcher)) return true; $model = $this->related->newFromBuilder((array) $attributes);
// We will append the names of the class to the event to distinguish it from $model->setParent($this);
// other model events that are fired, allowing us to listen on each model
// event set individually instead of catching event for all the models.
$event = "eloquent.{$event}: ".get_class($model);
$method = $halt ? 'until' : 'fire'; $model->setRelation($this->foreignKey, $this->parent);
return $dispatcher->$method($event, $model); // If you remove this, you will get segmentation faults!
$model->setHidden(array_merge($model->getHidden(), array($this->foreignKey)));
return $model;
} }
} }
...@@ -98,8 +98,7 @@ class EmbeddedRelationsTest extends TestCase { ...@@ -98,8 +98,7 @@ class EmbeddedRelationsTest extends TestCase {
$user = User::create(array('name' => 'John Doe')); $user = User::create(array('name' => 'John Doe'));
$address = new Address(array('city' => 'London')); $address = new Address(array('city' => 'London'));
$address = $user->addresses()->associate($address); $user->addresses()->associate($address);
$this->assertNotNull($user->_addresses);
$this->assertEquals(array('London'), $user->addresses->lists('city')); $this->assertEquals(array('London'), $user->addresses->lists('city'));
$this->assertNotNull($address->_id); $this->assertNotNull($address->_id);
...@@ -180,7 +179,7 @@ class EmbeddedRelationsTest extends TestCase { ...@@ -180,7 +179,7 @@ class EmbeddedRelationsTest extends TestCase {
$this->assertEquals(array('Bruxelles', 'Paris'), $freshUser->addresses->lists('city')); $this->assertEquals(array('Bruxelles', 'Paris'), $freshUser->addresses->lists('city'));
} }
public function testEmbedsManyDestroy() /*public function testEmbedsManyDestroy()
{ {
$user = User::create(array('name' => 'John Doe')); $user = User::create(array('name' => 'John Doe'));
$user->addresses()->saveMany(array(new Address(array('city' => 'London')), new Address(array('city' => 'Bristol')), new Address(array('city' => 'Bruxelles')))); $user->addresses()->saveMany(array(new Address(array('city' => 'London')), new Address(array('city' => 'Bristol')), new Address(array('city' => 'Bruxelles'))));
...@@ -216,7 +215,7 @@ class EmbeddedRelationsTest extends TestCase { ...@@ -216,7 +215,7 @@ class EmbeddedRelationsTest extends TestCase {
list($london, $bristol, $bruxelles) = $user->addresses()->saveMany(array(new Address(array('city' => 'London')), new Address(array('city' => 'Bristol')), new Address(array('city' => 'Bruxelles')))); list($london, $bristol, $bruxelles) = $user->addresses()->saveMany(array(new Address(array('city' => 'London')), new Address(array('city' => 'Bristol')), new Address(array('city' => 'Bruxelles'))));
$user->addresses()->destroy(array($london, $bruxelles)); $user->addresses()->destroy(array($london, $bruxelles));
$this->assertEquals(array('Bristol'), $user->addresses->lists('city')); $this->assertEquals(array('Bristol'), $user->addresses->lists('city'));
} }*/
public function testEmbedsManyDissociate() public function testEmbedsManyDissociate()
{ {
...@@ -391,7 +390,7 @@ class EmbeddedRelationsTest extends TestCase { ...@@ -391,7 +390,7 @@ class EmbeddedRelationsTest extends TestCase {
$father = $user->father()->save($father); $father = $user->father()->save($father);
$father->unsetEventDispatcher(); $father->unsetEventDispatcher();
$this->assertNotNull($user->_father); $this->assertNotNull($user->father);
$this->assertEquals('Mark Doe', $user->father->name); $this->assertEquals('Mark Doe', $user->father->name);
$this->assertInstanceOf('DateTime', $father->created_at); $this->assertInstanceOf('DateTime', $father->created_at);
$this->assertInstanceOf('DateTime', $father->updated_at); $this->assertInstanceOf('DateTime', $father->updated_at);
...@@ -411,7 +410,7 @@ class EmbeddedRelationsTest extends TestCase { ...@@ -411,7 +410,7 @@ class EmbeddedRelationsTest extends TestCase {
$user->father()->save($father); $user->father()->save($father);
$father->unsetEventDispatcher(); $father->unsetEventDispatcher();
$this->assertNotNull($user->_father); $this->assertNotNull($user->father);
$this->assertEquals('Tom Doe', $user->father->name); $this->assertEquals('Tom Doe', $user->father->name);
$father = new User(array('name' => 'Jim Doe')); $father = new User(array('name' => 'Jim Doe'));
...@@ -425,7 +424,7 @@ class EmbeddedRelationsTest extends TestCase { ...@@ -425,7 +424,7 @@ class EmbeddedRelationsTest extends TestCase {
$father = $user->father()->save($father); $father = $user->father()->save($father);
$father->unsetEventDispatcher(); $father->unsetEventDispatcher();
$this->assertNotNull($user->_father); $this->assertNotNull($user->father);
$this->assertEquals('Jim Doe', $user->father->name); $this->assertEquals('Jim Doe', $user->father->name);
} }
...@@ -440,7 +439,7 @@ class EmbeddedRelationsTest extends TestCase { ...@@ -440,7 +439,7 @@ class EmbeddedRelationsTest extends TestCase {
$father = $user->father()->associate($father); $father = $user->father()->associate($father);
$father->unsetEventDispatcher(); $father->unsetEventDispatcher();
$this->assertNotNull($user->_father); $this->assertNotNull($user->father);
$this->assertEquals('Mark Doe', $user->father->name); $this->assertEquals('Mark Doe', $user->father->name);
} }
...@@ -450,7 +449,6 @@ class EmbeddedRelationsTest extends TestCase { ...@@ -450,7 +449,6 @@ class EmbeddedRelationsTest extends TestCase {
$father = $user->father()->save(new User(array('name' => 'Mark Doe'))); $father = $user->father()->save(new User(array('name' => 'Mark Doe')));
$user->father()->delete(); $user->father()->delete();
$this->assertNull($user->_father);
$this->assertNull($user->father); $this->assertNull($user->father);
} }
...@@ -466,4 +464,24 @@ class EmbeddedRelationsTest extends TestCase { ...@@ -466,4 +464,24 @@ class EmbeddedRelationsTest extends TestCase {
$this->assertTrue(is_array($array['addresses'])); $this->assertTrue(is_array($array['addresses']));
} }
public function testEmbeddedSave()
{
$user = User::create(array('name' => 'John Doe'));
$address = $user->addresses()->create(array('city' => 'New York'));
$father = $user->father()->create(array('name' => 'Mark Doe'));
$address->city = 'Paris';
$address->save();
$father->name = 'Steve Doe';
$father->save();
$this->assertEquals('Paris', $user->addresses->first()->city);
$this->assertEquals('Steve Doe', $user->father->name);
$user = User::where('name', 'John Doe')->first();
$this->assertEquals('Paris', $user->addresses->first()->city);
$this->assertEquals('Steve Doe', $user->father->name);
}
} }
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