diff --git a/src/Jenssegers/Mongodb/Relations/EmbedsMany.php b/src/Jenssegers/Mongodb/Relations/EmbedsMany.php index 76eaac999..b59eb70ee 100644 --- a/src/Jenssegers/Mongodb/Relations/EmbedsMany.php +++ b/src/Jenssegers/Mongodb/Relations/EmbedsMany.php @@ -146,9 +146,10 @@ public function find($id) } $records = $this->getEmbeddedRecords(); - $primaryKey = $this->related->getKeyName(); + // Traverse all embedded records and find the first record + // that matches the given primary key. $record = array_first($records, function($itemKey, $record) use ($primaryKey, $id) { return $record[$primaryKey] == $id; @@ -283,6 +284,7 @@ public function destroy($ids = array()) { $ids = $this->getIdsArrayFrom($ids); + // Get all models matching the given ids. $models = $this->get()->only($ids); // Pull the documents from the database. @@ -302,21 +304,19 @@ public function dissociate($ids = array()) { $ids = $this->getIdsArrayFrom($ids); + $records = $this->getEmbeddedRecords(); $primaryKey = $this->related->getKeyName(); - // Get existing embedded documents. - $documents = $this->getEmbeddedRecords(); - // Remove the document from the parent model. - foreach ($documents as $i => $document) + foreach ($records as $i => $record) { - if (in_array($document[$primaryKey], $ids)) + if (in_array($record[$primaryKey], $ids)) { - unset($documents[$i]); + unset($records[$i]); } } - $this->setEmbeddedRecords($documents); + $this->setEmbeddedRecords($records); // We return the total number of deletes for the operation. The developers // can then check this number as a boolean type value or get this total count @@ -325,7 +325,32 @@ public function dissociate($ids = array()) } /** - * Delete alias. + * 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 the update query was successful, we will remove the embedded records + // of the parent instance. + if ($result) + { + $count = $this->count(); + + $this->setEmbeddedRecords(array()); + + // Return the number of deleted embedded records. + return $count; + } + + return $result; + } + + /** + * Destroy alias. * * @param mixed $ids * @return int @@ -356,14 +381,20 @@ protected function performInsert(Model $model) { if ($this->fireModelEvent($model, 'creating') === false) return false; - // Associate the new model to the parent. - $this->associateNew($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); if ($result) { + // Associate the new model to the parent. + $this->associateNew($model); + $this->fireModelEvent($model, 'created', false); return $model; @@ -382,9 +413,6 @@ 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); @@ -394,6 +422,9 @@ protected function performUpdate(Model $model) if ($result) { + // Update the related model in the parent instance + $this->associateExisting($model); + $this->fireModelEvent($model, 'updated', false); return $model; @@ -438,18 +469,18 @@ protected function performDelete(Model $model) */ protected function associateNew($model) { - // Create a new key. + // Create a new key if needed. if ( ! $model->getAttribute('_id')) { $model->setAttribute('_id', new MongoId); } - $documents = $this->getEmbeddedRecords(); + $records = $this->getEmbeddedRecords(); // Add the document to the parent model. - $documents[] = $model->getAttributes(); + $records[] = $model->getAttributes(); - $this->setEmbeddedRecords($documents); + $this->setEmbeddedRecords($records); // Mark the model as existing. $model->exists = true; @@ -466,23 +497,22 @@ protected function associateNew($model) protected function associateExisting($model) { // Get existing embedded documents. - $documents = $this->getEmbeddedRecords(); + $records = $this->getEmbeddedRecords(); $primaryKey = $this->related->getKeyName(); - $key = $model->getKey(); // Replace the document in the parent model. - foreach ($documents as &$document) + foreach ($records as &$record) { - if ($document[$primaryKey] == $key) + if ($record[$primaryKey] == $key) { - $document = $model->getAttributes(); + $record = $model->getAttributes(); break; } } - $this->setEmbeddedRecords($documents); + $this->setEmbeddedRecords($records); return $model; } diff --git a/tests/RelationsTest.php b/tests/RelationsTest.php index b46489932..8eb68e594 100644 --- a/tests/RelationsTest.php +++ b/tests/RelationsTest.php @@ -609,4 +609,28 @@ public function testEmbedsManyEagerLoading() $this->assertEquals(2, $relations['addresses']->count()); } + public function testEmbedsManyDelete() + { + $user1 = User::create(array('name' => 'John Doe')); + $user1->addresses()->save(new Address(array('city' => 'New York'))); + $user1->addresses()->save(new Address(array('city' => 'Paris'))); + + $user2 = User::create(array('name' => 'Jane Doe')); + $user2->addresses()->save(new Address(array('city' => 'Berlin'))); + $user2->addresses()->save(new Address(array('city' => 'Paris'))); + + $user1->addresses()->delete(); + $this->assertEquals(0, $user1->addresses()->count()); + $this->assertEquals(0, $user1->addresses->count()); + $this->assertEquals(2, $user2->addresses()->count()); + $this->assertEquals(2, $user2->addresses->count()); + + $user1 = User::find($user1->id); + $user2 = User::find($user2->id); + $this->assertEquals(0, $user1->addresses()->count()); + $this->assertEquals(0, $user1->addresses->count()); + $this->assertEquals(2, $user2->addresses()->count()); + $this->assertEquals(2, $user2->addresses->count()); + } + }