diff --git a/CHANGELOG.md b/CHANGELOG.md
index c85e5efa3..160b0b927 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,3 +2,5 @@
All notable changes to this project will be documented in this file.
## [Unreleased]
+### Removed
+- EmbedsOne and EmbedsMany relations by [@divine](https://github.com/divine).
diff --git a/README.md b/README.md
index 91bfa8c6f..4f1359972 100644
--- a/README.md
+++ b/README.md
@@ -30,8 +30,6 @@ This package adds functionalities to the Eloquent model and Query builder for Mo
- [Relationships](#relationships)
- [Basic Usage](#basic-usage-1)
- [belongsToMany and pivots](#belongstomany-and-pivots)
- - [EmbedsMany Relationship](#embedsmany-relationship)
- - [EmbedsOne Relationship](#embedsone-relationship)
- [Query Builder](#query-builder)
- [Basic Usage](#basic-usage-2)
- [Available operations](#available-operations)
@@ -419,7 +417,7 @@ Aggregations can be also used on sub-documents:
$total = Order::max('suborder.price');
```
-**NOTE**: This aggregation only works with single sub-documents (like `EmbedsOne`) not subdocument arrays (like `EmbedsMany`).
+**NOTE**: This aggregation only works with single sub-documents not arrays.
**Incrementing/Decrementing the value of a column**
@@ -712,10 +710,6 @@ The only available relationships are:
- belongsTo
- belongsToMany
-The MongoDB-specific relationships are:
- - embedsOne
- - embedsMany
-
Here is a small example:
```php
@@ -764,152 +758,6 @@ class User extends Model
}
```
-### EmbedsMany Relationship
-
-If you want to embed models, rather than referencing them, you can use the `embedsMany` relation. This relation is similar to the `hasMany` relation but embeds the models inside the parent object.
-
-**REMEMBER**: These relations return Eloquent collections, they don't return query builder objects!
-
-```php
-use Jenssegers\Mongodb\Eloquent\Model;
-
-class User extends Model
-{
- public function books()
- {
- return $this->embedsMany(Book::class);
- }
-}
-```
-
-You can access the embedded models through the dynamic property:
-
-```php
-$user = User::first();
-
-foreach ($user->books as $book) {
- //
-}
-```
-
-The inverse relation is auto*magically* available. You don't need to define this reverse relation.
-
-```php
-$book = Book::first();
-
-$user = $book->user;
-```
-
-Inserting and updating embedded models works similar to the `hasMany` relation:
-
-```php
-$book = $user->books()->save(
- new Book(['title' => 'A Game of Thrones'])
-);
-
-// or
-$book =
- $user->books()
- ->create(['title' => 'A Game of Thrones']);
-```
-
-You can update embedded models using their `save` method (available since release 2.0.0):
-
-```php
-$book = $user->books()->first();
-
-$book->title = 'A Game of Thrones';
-$book->save();
-```
-
-You can remove an embedded model by using the `destroy` method on the relation, or the `delete` method on the model (available since release 2.0.0):
-
-```php
-$book->delete();
-
-// Similar operation
-$user->books()->destroy($book);
-```
-
-If you want to add or remove an embedded model, without touching the database, you can use the `associate` and `dissociate` methods.
-
-To eventually write the changes to the database, save the parent object:
-
-```php
-$user->books()->associate($book);
-$user->save();
-```
-
-Like other relations, embedsMany assumes the local key of the relationship based on the model name. You can override the default local key by passing a second argument to the embedsMany method:
-
-```php
-use Jenssegers\Mongodb\Eloquent\Model;
-
-class User extends Model
-{
- public function books()
- {
- return $this->embedsMany(Book::class, 'local_key');
- }
-}
-```
-
-Embedded relations will return a Collection of embedded items instead of a query builder. Check out the available operations here: https://laravel.com/docs/master/collections
-
-
-### EmbedsOne Relationship
-
-The embedsOne relation is similar to the embedsMany relation, but only embeds a single model.
-
-```php
-use Jenssegers\Mongodb\Eloquent\Model;
-
-class Book extends Model
-{
- public function author()
- {
- return $this->embedsOne(Author::class);
- }
-}
-```
-
-You can access the embedded models through the dynamic property:
-
-```php
-$book = Book::first();
-$author = $book->author;
-```
-
-Inserting and updating embedded models works similar to the `hasOne` relation:
-
-```php
-$author = $book->author()->save(
- new Author(['name' => 'John Doe'])
-);
-
-// Similar
-$author =
- $book->author()
- ->create(['name' => 'John Doe']);
-```
-
-You can update the embedded model using the `save` method (available since release 2.0.0):
-
-```php
-$author = $book->author;
-
-$author->name = 'Jane Doe';
-$author->save();
-```
-
-You can replace the embedded model with a new model like this:
-
-```php
-$newAuthor = new Author(['name' => 'Jane Doe']);
-
-$book->author()->save($newAuthor);
-```
-
Query Builder
-------------
@@ -1098,39 +946,10 @@ Jenssegers\Mongodb\MongodbQueueServiceProvider::class,
Upgrading
---------
-#### Upgrading from version 2 to 3
-
-In this new major release which supports the new MongoDB PHP extension, we also moved the location of the Model class and replaced the MySQL model class with a trait.
+#### Upgrading from version 3 to 4
-Please change all `Jenssegers\Mongodb\Model` references to `Jenssegers\Mongodb\Eloquent\Model` either at the top of your model files or your registered alias.
+This new major release contains breaking changes which is listed below:
-```php
-use Jenssegers\Mongodb\Eloquent\Model;
+- EmbedsOne and EmbedsMany relations has been removed completely. See explanation [here](https://github.com/jenssegers/laravel-mongodb/issues/1974#issuecomment-592859508)
-class User extends Model
-{
- //
-}
-```
-
-If you are using hybrid relations, your MySQL classes should now extend the original Eloquent model class `Illuminate\Database\Eloquent\Model` instead of the removed `Jenssegers\Eloquent\Model`.
-
-Instead use the new `Jenssegers\Mongodb\Eloquent\HybridRelations` trait. This should make things more clear as there is only one single model class in this package.
-
-```php
-use Jenssegers\Mongodb\Eloquent\HybridRelations;
-
-class User extends Model
-{
-
- use HybridRelations;
-
- protected $connection = 'mysql';
-}
-```
-
-Embedded relations now return an `Illuminate\Database\Eloquent\Collection` rather than a custom Collection class. If you were using one of the special methods that were available, convert them to Collection operations.
-
-```php
-$books = $user->books()->sortBy('title')->get();
-```
+For any other minor changes, please take a look at our [changelog](CHANGELOG.md)
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 4da34b41d..865f8bcd5 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -31,7 +31,6 @@
tests/RelationsTest.php
- tests/EmbeddedRelationsTest.php
tests/RelationsTest.php
diff --git a/src/Jenssegers/Mongodb/Eloquent/Builder.php b/src/Jenssegers/Mongodb/Eloquent/Builder.php
index 90b58484f..89206c0d6 100644
--- a/src/Jenssegers/Mongodb/Eloquent/Builder.php
+++ b/src/Jenssegers/Mongodb/Eloquent/Builder.php
@@ -35,14 +35,6 @@ class Builder extends EloquentBuilder
*/
public function update(array $values, array $options = [])
{
- // Intercept operations on embedded models and delegate logic
- // to the parent relation instance.
- if ($relation = $this->model->getParentRelation()) {
- $relation->performUpdate($this->model, $values);
-
- return 1;
- }
-
return $this->toBase()->update($this->addUpdatedAtColumn($values), $options);
}
@@ -51,14 +43,6 @@ public function update(array $values, array $options = [])
*/
public function insert(array $values)
{
- // Intercept operations on embedded models and delegate logic
- // to the parent relation instance.
- if ($relation = $this->model->getParentRelation()) {
- $relation->performInsert($this->model, $values);
-
- return true;
- }
-
return parent::insert($values);
}
@@ -67,14 +51,6 @@ public function insert(array $values)
*/
public function insertGetId(array $values, $sequence = null)
{
- // Intercept operations on embedded models and delegate logic
- // to the parent relation instance.
- if ($relation = $this->model->getParentRelation()) {
- $relation->performInsert($this->model, $values);
-
- return $this->model->getKey();
- }
-
return parent::insertGetId($values, $sequence);
}
@@ -83,14 +59,6 @@ public function insertGetId(array $values, $sequence = null)
*/
public function delete()
{
- // Intercept operations on embedded models and delegate logic
- // to the parent relation instance.
- if ($relation = $this->model->getParentRelation()) {
- $relation->performDelete($this->model);
-
- return $this->model->getKey();
- }
-
return parent::delete();
}
@@ -99,23 +67,6 @@ public function delete()
*/
public function increment($column, $amount = 1, array $extra = [])
{
- // Intercept operations on embedded models and delegate logic
- // to the parent relation instance.
- if ($relation = $this->model->getParentRelation()) {
- $value = $this->model->{$column};
-
- // When doing increment and decrements, Eloquent will automatically
- // sync the original attributes. We need to change the attribute
- // temporary in order to trigger an update query.
- $this->model->{$column} = null;
-
- $this->model->syncOriginalAttribute($column);
-
- $result = $this->model->update([$column => $value]);
-
- return $result;
- }
-
return parent::increment($column, $amount, $extra);
}
@@ -124,21 +75,6 @@ public function increment($column, $amount = 1, array $extra = [])
*/
public function decrement($column, $amount = 1, array $extra = [])
{
- // Intercept operations on embedded models and delegate logic
- // to the parent relation instance.
- if ($relation = $this->model->getParentRelation()) {
- $value = $this->model->{$column};
-
- // When doing increment and decrements, Eloquent will automatically
- // sync the original attributes. We need to change the attribute
- // temporary in order to trigger an update query.
- $this->model->{$column} = null;
-
- $this->model->syncOriginalAttribute($column);
-
- return $this->model->update([$column => $value]);
- }
-
return parent::decrement($column, $amount, $extra);
}
diff --git a/src/Jenssegers/Mongodb/Eloquent/EmbedsRelations.php b/src/Jenssegers/Mongodb/Eloquent/EmbedsRelations.php
deleted file mode 100644
index caef0e693..000000000
--- a/src/Jenssegers/Mongodb/Eloquent/EmbedsRelations.php
+++ /dev/null
@@ -1,78 +0,0 @@
-newQuery();
-
- $instance = new $related;
-
- return new EmbedsMany($query, $this, $instance, $localKey, $foreignKey, $relation);
- }
-
- /**
- * Define an embedded one-to-many relationship.
- * @param string $related
- * @param string $localKey
- * @param string $foreignKey
- * @param string $relation
- * @return \Jenssegers\Mongodb\Relations\EmbedsOne
- */
- protected function embedsOne($related, $localKey = null, $foreignKey = null, $relation = null)
- {
- // 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 relationships.
- if ($relation === null) {
- list(, $caller) = debug_backtrace(false);
-
- $relation = $caller['function'];
- }
-
- if ($localKey === null) {
- $localKey = $relation;
- }
-
- if ($foreignKey === null) {
- $foreignKey = Str::snake(class_basename($this));
- }
-
- $query = $this->newQuery();
-
- $instance = new $related;
-
- return new EmbedsOne($query, $this, $instance, $localKey, $foreignKey, $relation);
- }
-}
diff --git a/src/Jenssegers/Mongodb/Eloquent/Model.php b/src/Jenssegers/Mongodb/Eloquent/Model.php
index 54ef5129b..27e0228fe 100644
--- a/src/Jenssegers/Mongodb/Eloquent/Model.php
+++ b/src/Jenssegers/Mongodb/Eloquent/Model.php
@@ -17,7 +17,7 @@
abstract class Model extends BaseModel
{
- use HybridRelations, EmbedsRelations;
+ use HybridRelations;
/**
* The collection associated with the model.
@@ -143,11 +143,6 @@ public function getAttribute($key)
return $this->getAttributeValue($key);
}
- // This checks for embedded relation support.
- if (method_exists($this, $key) && !method_exists(self::class, $key)) {
- return $this->getRelationValue($key);
- }
-
return parent::getAttribute($key);
}
diff --git a/src/Jenssegers/Mongodb/Relations/EmbedsMany.php b/src/Jenssegers/Mongodb/Relations/EmbedsMany.php
deleted file mode 100644
index eda777e8d..000000000
--- a/src/Jenssegers/Mongodb/Relations/EmbedsMany.php
+++ /dev/null
@@ -1,342 +0,0 @@
-setRelation($relation, $this->related->newCollection());
- }
-
- return $models;
- }
-
- /**
- * @inheritdoc
- */
- public function getResults()
- {
- return $this->toCollection($this->getEmbedded());
- }
-
- /**
- * Save a new model and attach it to the parent model.
- * @param Model $model
- * @return Model|bool
- */
- public function performInsert(Model $model)
- {
- // Generate a new key if needed.
- if ($model->getKeyName() == '_id' && !$model->getKey()) {
- $model->setAttribute('_id', new ObjectID);
- }
-
- // For deeply nested documents, let the parent handle the changes.
- if ($this->isNested()) {
- $this->associate($model);
- return $this->parent->save() ? $model : false;
- }
-
- // Push the new model to the database.
- $result = $this->getBaseQuery()->push($this->localKey, $model->getAttributes(), true);
-
- // Attach the model to its parent.
- if ($result) {
- $this->associate($model);
- }
-
- return $result ? $model : false;
- }
-
- /**
- * Save an existing model and attach it to the parent model.
- * @param Model $model
- * @return Model|bool
- */
- public function performUpdate(Model $model)
- {
- // For deeply nested documents, let the parent handle the changes.
- if ($this->isNested()) {
- $this->associate($model);
-
- return $this->parent->save();
- }
-
- // Get the correct foreign key value.
- $foreignKey = $this->getForeignKeyValue($model);
-
- $values = $this->getUpdateValues($model->getDirty(), $this->localKey . '.$.');
-
- // Update document in database.
- $result = $this->getBaseQuery()->where($this->localKey . '.' . $model->getKeyName(), $foreignKey)
- ->update($values);
-
- // Attach the model to its parent.
- if ($result) {
- $this->associate($model);
- }
-
- return $result ? $model : false;
- }
-
- /**
- * Delete an existing model and detach it from the parent model.
- * @param Model $model
- * @return int
- */
- public function performDelete(Model $model)
- {
- // For deeply nested documents, let the parent handle the changes.
- if ($this->isNested()) {
- $this->dissociate($model);
-
- return $this->parent->save();
- }
-
- // Get the correct foreign key value.
- $foreignKey = $this->getForeignKeyValue($model);
-
- $result = $this->getBaseQuery()->pull($this->localKey, [$model->getKeyName() => $foreignKey]);
-
- if ($result) {
- $this->dissociate($model);
- }
-
- return $result;
- }
-
- /**
- * Associate the model instance to the given parent, without saving it to the database.
- * @param Model $model
- * @return Model
- */
- public function associate(Model $model)
- {
- if (!$this->contains($model)) {
- return $this->associateNew($model);
- }
-
- return $this->associateExisting($model);
- }
-
- /**
- * Dissociate the model instance from the given parent, without saving it to the database.
- * @param mixed $ids
- * @return int
- */
- public function dissociate($ids = [])
- {
- $ids = $this->getIdsArrayFrom($ids);
-
- $records = $this->getEmbedded();
-
- $primaryKey = $this->related->getKeyName();
-
- // Remove the document from the parent model.
- foreach ($records as $i => $record) {
- if (in_array($record[$primaryKey], $ids)) {
- unset($records[$i]);
- }
- }
-
- $this->setEmbedded($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
- // of records deleted for logging, etc.
- return count($ids);
- }
-
- /**
- * Destroy the embedded models for the given IDs.
- * @param mixed $ids
- * @return int
- */
- public function destroy($ids = [])
- {
- $count = 0;
-
- $ids = $this->getIdsArrayFrom($ids);
-
- // Get all models matching the given ids.
- $models = $this->getResults()->only($ids);
-
- // Pull the documents from the database.
- foreach ($models as $model) {
- if ($model->delete()) {
- $count++;
- }
- }
-
- return $count;
- }
-
- /**
- * Delete all embedded models.
- * @return int
- */
- public function delete()
- {
- // Overwrite the local key with an empty array.
- $result = $this->query->update([$this->localKey => []]);
-
- if ($result) {
- $this->setEmbedded([]);
- }
-
- return $result;
- }
-
- /**
- * Destroy alias.
- * @param mixed $ids
- * @return int
- */
- public function detach($ids = [])
- {
- return $this->destroy($ids);
- }
-
- /**
- * Save alias.
- * @param Model $model
- * @return Model
- */
- public function attach(Model $model)
- {
- return $this->save($model);
- }
-
- /**
- * Associate a new model instance to the given parent, without saving it to the database.
- * @param Model $model
- * @return Model
- */
- protected function associateNew($model)
- {
- // Create a new key if needed.
- if ($model->getKeyName() === '_id' && !$model->getAttribute('_id')) {
- $model->setAttribute('_id', new ObjectID);
- }
-
- $records = $this->getEmbedded();
-
- // Add the new model to the embedded documents.
- $records[] = $model->getAttributes();
-
- return $this->setEmbedded($records);
- }
-
- /**
- * Associate an existing model instance to the given parent, without saving it to the database.
- * @param Model $model
- * @return Model
- */
- protected function associateExisting($model)
- {
- // Get existing embedded documents.
- $records = $this->getEmbedded();
-
- $primaryKey = $this->related->getKeyName();
-
- $key = $model->getKey();
-
- // Replace the document in the parent model.
- foreach ($records as &$record) {
- if ($record[$primaryKey] == $key) {
- $record = $model->getAttributes();
- break;
- }
- }
-
- return $this->setEmbedded($records);
- }
-
- /**
- * @param null $perPage
- * @param array $columns
- * @param string $pageName
- * @param null $page
- * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
- */
- public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
- {
- $page = $page ?: Paginator::resolveCurrentPage($pageName);
- $perPage = $perPage ?: $this->related->getPerPage();
-
- $results = $this->getEmbedded();
- $results = $this->toCollection($results);
- $total = $results->count();
- $start = ($page - 1) * $perPage;
-
- $sliced = $results->slice(
- $start,
- $perPage
- );
-
- return new LengthAwarePaginator(
- $sliced,
- $total,
- $perPage,
- $page,
- [
- 'path' => Paginator::resolveCurrentPath()
- ]
- );
- }
-
- /**
- * @inheritdoc
- */
- protected function getEmbedded()
- {
- return parent::getEmbedded() ?: [];
- }
-
- /**
- * @inheritdoc
- */
- protected function setEmbedded($models)
- {
- if (!is_array($models)) {
- $models = [$models];
- }
-
- return parent::setEmbedded(array_values($models));
- }
-
- /**
- * @inheritdoc
- */
- public function __call($method, $parameters)
- {
- if (method_exists(Collection::class, $method)) {
- return call_user_func_array([$this->getResults(), $method], $parameters);
- }
-
- return parent::__call($method, $parameters);
- }
-
- /**
- * Get the name of the "where in" method for eager loading.
- * @param \Illuminate\Database\Eloquent\Model $model
- * @param string $key
- * @return string
- */
- protected function whereInMethod(EloquentModel $model, $key)
- {
- return 'whereIn';
- }
-}
diff --git a/src/Jenssegers/Mongodb/Relations/EmbedsOne.php b/src/Jenssegers/Mongodb/Relations/EmbedsOne.php
deleted file mode 100644
index a0e713bc1..000000000
--- a/src/Jenssegers/Mongodb/Relations/EmbedsOne.php
+++ /dev/null
@@ -1,145 +0,0 @@
-setRelation($relation, null);
- }
-
- return $models;
- }
-
- /**
- * @inheritdoc
- */
- public function getResults()
- {
- return $this->toModel($this->getEmbedded());
- }
-
- /**
- * Save a new model and attach it to the parent model.
- * @param Model $model
- * @return Model|bool
- */
- public function performInsert(Model $model)
- {
- // Generate a new key if needed.
- if ($model->getKeyName() == '_id' && !$model->getKey()) {
- $model->setAttribute('_id', new ObjectID);
- }
-
- // For deeply nested documents, let the parent handle the changes.
- if ($this->isNested()) {
- $this->associate($model);
- return $this->parent->save() ? $model : false;
- }
-
- $result = $this->getBaseQuery()->update([$this->localKey => $model->getAttributes()]);
-
- // Attach the model to its parent.
- if ($result) {
- $this->associate($model);
- }
-
- return $result ? $model : false;
- }
-
- /**
- * Save an existing model and attach it to the parent model.
- * @param Model $model
- * @return Model|bool
- */
- public function performUpdate(Model $model)
- {
- if ($this->isNested()) {
- $this->associate($model);
-
- return $this->parent->save();
- }
-
- $values = $this->getUpdateValues($model->getDirty(), $this->localKey . '.');
-
- $result = $this->getBaseQuery()->update($values);
-
- // Attach the model to its parent.
- if ($result) {
- $this->associate($model);
- }
-
- return $result ? $model : false;
- }
-
- /**
- * Delete an existing model and detach it from the parent model.
- * @return int
- */
- public function performDelete()
- {
- // For deeply nested documents, let the parent handle the changes.
- if ($this->isNested()) {
- $this->dissociate();
- return $this->parent->save();
- }
-
- // Overwrite the local key with an empty array.
- $result = $this->getBaseQuery()->update([$this->localKey => null]);
-
- // Detach the model from its parent.
- if ($result) {
- $this->dissociate();
- }
-
- return $result;
- }
-
- /**
- * Attach the model to its parent.
- * @param Model $model
- * @return Model
- */
- public function associate(Model $model)
- {
- return $this->setEmbedded($model->getAttributes());
- }
-
- /**
- * Detach the model from its parent.
- * @return Model
- */
- public function dissociate()
- {
- return $this->setEmbedded(null);
- }
-
- /**
- * Delete all embedded models.
- * @return int
- */
- public function delete()
- {
- return $this->performDelete();
- }
-
- /**
- * Get the name of the "where in" method for eager loading.
- * @param \Illuminate\Database\Eloquent\Model $model
- * @param string $key
- * @return string
- */
- protected function whereInMethod(EloquentModel $model, $key)
- {
- return 'whereIn';
- }
-}
diff --git a/src/Jenssegers/Mongodb/Relations/EmbedsOneOrMany.php b/src/Jenssegers/Mongodb/Relations/EmbedsOneOrMany.php
deleted file mode 100644
index 5a7f636e7..000000000
--- a/src/Jenssegers/Mongodb/Relations/EmbedsOneOrMany.php
+++ /dev/null
@@ -1,397 +0,0 @@
-query = $query;
- $this->parent = $parent;
- $this->related = $related;
- $this->localKey = $localKey;
- $this->foreignKey = $foreignKey;
- $this->relation = $relation;
-
- // If this is a nested relation, we need to get the parent query instead.
- if ($parentRelation = $this->getParentRelation()) {
- $this->query = $parentRelation->getQuery();
- }
-
- $this->addConstraints();
- }
-
- /**
- * @inheritdoc
- */
- public function addConstraints()
- {
- if (static::$constraints) {
- $this->query->where($this->getQualifiedParentKeyName(), '=', $this->getParentKey());
- }
- }
-
- /**
- * @inheritdoc
- */
- public function addEagerConstraints(array $models)
- {
- // There are no eager loading constraints.
- }
-
- /**
- * @inheritdoc
- */
- public function match(array $models, Collection $results, $relation)
- {
- foreach ($models as $model) {
- $results = $model->$relation()->getResults();
-
- $model->setParentRelation($this);
-
- $model->setRelation($relation, $results);
- }
-
- return $models;
- }
-
- /**
- * Shorthand to get the results of the relationship.
- * @param array $columns
- * @return Collection
- */
- public function get($columns = ['*'])
- {
- return $this->getResults();
- }
-
- /**
- * Get the number of embedded models.
- * @return int
- */
- public function count()
- {
- return count($this->getEmbedded());
- }
-
- /**
- * Attach a model instance to the parent model.
- * @param Model $model
- * @return Model|bool
- */
- public function save(Model $model)
- {
- $model->setParentRelation($this);
-
- return $model->save() ? $model : false;
- }
-
- /**
- * Attach a collection of models to the parent instance.
- * @param Collection|array $models
- * @return Collection|array
- */
- public function saveMany($models)
- {
- foreach ($models as $model) {
- $this->save($model);
- }
-
- return $models;
- }
-
- /**
- * Create a new instance of the related model.
- * @param array $attributes
- * @return Model
- */
- public function create(array $attributes = [])
- {
- // 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
- // on the models. Otherwise, some of these attributes will not get set.
- $instance = $this->related->newInstance($attributes);
-
- $instance->setParentRelation($this);
-
- $instance->save();
-
- return $instance;
- }
-
- /**
- * Create an array of new instances of the related model.
- * @param array $records
- * @return array
- */
- public function createMany(array $records)
- {
- $instances = [];
-
- foreach ($records as $record) {
- $instances[] = $this->create($record);
- }
-
- return $instances;
- }
-
- /**
- * Transform single ID, single Model or array of Models into an array of IDs.
- * @param mixed $ids
- * @return array
- */
- protected function getIdsArrayFrom($ids)
- {
- if ($ids instanceof \Illuminate\Support\Collection) {
- $ids = $ids->all();
- }
-
- if (!is_array($ids)) {
- $ids = [$ids];
- }
-
- foreach ($ids as &$id) {
- if ($id instanceof Model) {
- $id = $id->getKey();
- }
- }
-
- return $ids;
- }
-
- /**
- * @inheritdoc
- */
- protected function getEmbedded()
- {
- // Get raw attributes to skip relations and accessors.
- $attributes = $this->parent->getAttributes();
-
- // Get embedded models form parent attributes.
- $embedded = isset($attributes[$this->localKey]) ? (array) $attributes[$this->localKey] : null;
-
- return $embedded;
- }
-
- /**
- * @inheritdoc
- */
- protected function setEmbedded($records)
- {
- // Assign models to parent attributes array.
- $attributes = $this->parent->getAttributes();
- $attributes[$this->localKey] = $records;
-
- // Set raw attributes to skip mutators.
- $this->parent->setRawAttributes($attributes);
-
- // Set the relation on the parent.
- return $this->parent->setRelation($this->relation, $records === null ? null : $this->getResults());
- }
-
- /**
- * Get the foreign key value for the relation.
- * @param mixed $id
- * @return mixed
- */
- protected function getForeignKeyValue($id)
- {
- if ($id instanceof Model) {
- $id = $id->getKey();
- }
-
- // Convert the id to MongoId if necessary.
- return $this->getBaseQuery()->convertKey($id);
- }
-
- /**
- * Convert an array of records to a Collection.
- * @param array $records
- * @return Collection
- */
- protected function toCollection(array $records = [])
- {
- $models = [];
-
- foreach ($records as $attributes) {
- $models[] = $this->toModel($attributes);
- }
-
- if (count($models) > 0) {
- $models = $this->eagerLoadRelations($models);
- }
-
- return $this->related->newCollection($models);
- }
-
- /**
- * Create a related model instanced.
- * @param array $attributes
- * @return Model
- */
- protected function toModel($attributes = [])
- {
- if ($attributes === null) {
- return;
- }
-
- $connection = $this->related->getConnection();
-
- $model = $this->related->newFromBuilder(
- (array) $attributes,
- $connection ? $connection->getName() : null
- );
-
- $model->setParentRelation($this);
-
- $model->setRelation($this->foreignKey, $this->parent);
-
- // If you remove this, you will get segmentation faults!
- $model->setHidden(array_merge($model->getHidden(), [$this->foreignKey]));
-
- return $model;
- }
-
- /**
- * Get the relation instance of the parent.
- * @return Relation
- */
- protected function getParentRelation()
- {
- return $this->parent->getParentRelation();
- }
-
- /**
- * @inheritdoc
- */
- public function getQuery()
- {
- // Because we are sharing this relation instance to models, we need
- // to make sure we use separate query instances.
- return clone $this->query;
- }
-
- /**
- * @inheritdoc
- */
- public function getBaseQuery()
- {
- // Because we are sharing this relation instance to models, we need
- // to make sure we use separate query instances.
- return clone $this->query->getQuery();
- }
-
- /**
- * Check if this relation is nested in another relation.
- * @return bool
- */
- protected function isNested()
- {
- return $this->getParentRelation() != null;
- }
-
- /**
- * Get the fully qualified local key name.
- * @param string $glue
- * @return string
- */
- protected function getPathHierarchy($glue = '.')
- {
- if ($parentRelation = $this->getParentRelation()) {
- return $parentRelation->getPathHierarchy($glue) . $glue . $this->localKey;
- }
-
- return $this->localKey;
- }
-
- /**
- * @inheritdoc
- */
- public function getQualifiedParentKeyName()
- {
- if ($parentRelation = $this->getParentRelation()) {
- return $parentRelation->getPathHierarchy() . '.' . $this->parent->getKeyName();
- }
-
- return $this->parent->getKeyName();
- }
-
- /**
- * Get the primary key value of the parent.
- * @return string
- */
- protected function getParentKey()
- {
- return $this->parent->getKey();
- }
-
- /**
- * Return update values
- * @param $array
- * @param string $prepend
- * @return array
- */
- public static function getUpdateValues($array, $prepend = '')
- {
- $results = [];
-
- foreach ($array as $key => $value) {
- $results[$prepend . $key] = $value;
- }
-
- return $results;
- }
-
- /**
- * Get the foreign key for the relationship.
- * @return string
- */
- public function getQualifiedForeignKeyName()
- {
- return $this->foreignKey;
- }
-
- /**
- * Get the name of the "where in" method for eager loading.
- * @param \Illuminate\Database\Eloquent\Model $model
- * @param string $key
- * @return string
- */
- protected function whereInMethod(EloquentModel $model, $key)
- {
- return 'whereIn';
- }
-}
diff --git a/tests/EmbeddedRelationsTest.php b/tests/EmbeddedRelationsTest.php
deleted file mode 100644
index 23e2fae03..000000000
--- a/tests/EmbeddedRelationsTest.php
+++ /dev/null
@@ -1,872 +0,0 @@
- 'John Doe']);
- $address = new Address(['city' => 'London']);
-
- $address->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($address), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.saving: ' . get_class($address), $address)
- ->andReturn(true);
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.creating: ' . get_class($address), $address)
- ->andReturn(true);
- $events->shouldReceive('dispatch')->once()->with('eloquent.created: ' . get_class($address), $address);
- $events->shouldReceive('dispatch')->once()->with('eloquent.saved: ' . get_class($address), $address);
-
- $address = $user->addresses()->save($address);
- $address->unsetEventDispatcher();
-
- $this->assertNotNull($user->addresses);
- $this->assertInstanceOf(Collection::class, $user->addresses);
- $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
- $this->assertInstanceOf(DateTime::class, $address->created_at);
- $this->assertInstanceOf(DateTime::class, $address->updated_at);
- $this->assertNotNull($address->_id);
- $this->assertIsString($address->_id);
-
- $raw = $address->getAttributes();
- $this->assertInstanceOf(ObjectId::class, $raw['_id']);
-
- $address = $user->addresses()->save(new Address(['city' => 'Paris']));
-
- $user = User::find($user->_id);
- $this->assertEquals(['London', 'Paris'], $user->addresses->pluck('city')->all());
-
- $address->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($address), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.saving: ' . get_class($address), $address)
- ->andReturn(true);
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.updating: ' . get_class($address), $address)
- ->andReturn(true);
- $events->shouldReceive('dispatch')->once()->with('eloquent.updated: ' . get_class($address), $address);
- $events->shouldReceive('dispatch')->once()->with('eloquent.saved: ' . get_class($address), $address);
-
- $address->city = 'New York';
- $user->addresses()->save($address);
- $address->unsetEventDispatcher();
-
- $this->assertCount(2, $user->addresses);
- $this->assertCount(2, $user->addresses()->get());
- $this->assertEquals(2, $user->addresses->count());
- $this->assertEquals(2, $user->addresses()->count());
- $this->assertEquals(['London', 'New York'], $user->addresses->pluck('city')->all());
-
- $freshUser = User::find($user->_id);
- $this->assertEquals(['London', 'New York'], $freshUser->addresses->pluck('city')->all());
-
- $address = $user->addresses->first();
- $this->assertEquals('London', $address->city);
- $this->assertInstanceOf(DateTime::class, $address->created_at);
- $this->assertInstanceOf(DateTime::class, $address->updated_at);
- $this->assertInstanceOf(User::class, $address->user);
- $this->assertEmpty($address->relationsToArray()); // prevent infinite loop
-
- $user = User::find($user->_id);
- $user->addresses()->save(new Address(['city' => 'Bruxelles']));
- $this->assertEquals(['London', 'New York', 'Bruxelles'], $user->addresses->pluck('city')->all());
-
- $address = $user->addresses[1];
- $address->city = "Manhattan";
- $user->addresses()->save($address);
- $this->assertEquals(['London', 'Manhattan', 'Bruxelles'], $user->addresses->pluck('city')->all());
-
- $freshUser = User::find($user->_id);
- $this->assertEquals(['London', 'Manhattan', 'Bruxelles'], $freshUser->addresses->pluck('city')->all());
- }
-
- public function testEmbedsToArray()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->saveMany([new Address(['city' => 'London']), new Address(['city' => 'Bristol'])]);
-
- $array = $user->toArray();
- $this->assertArrayNotHasKey('_addresses', $array);
- $this->assertArrayHasKey('addresses', $array);
- }
-
- public function testEmbedsManyAssociate()
- {
- $user = User::create(['name' => 'John Doe']);
- $address = new Address(['city' => 'London']);
-
- $user->addresses()->associate($address);
- $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
- $this->assertNotNull($address->_id);
-
- $freshUser = User::find($user->_id);
- $this->assertEquals([], $freshUser->addresses->pluck('city')->all());
-
- $address->city = 'Londinium';
- $user->addresses()->associate($address);
- $this->assertEquals(['Londinium'], $user->addresses->pluck('city')->all());
-
- $freshUser = User::find($user->_id);
- $this->assertEquals([], $freshUser->addresses->pluck('city')->all());
- }
-
- public function testEmbedsManySaveMany()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->saveMany([new Address(['city' => 'London']), new Address(['city' => 'Bristol'])]);
- $this->assertEquals(['London', 'Bristol'], $user->addresses->pluck('city')->all());
-
- $freshUser = User::find($user->id);
- $this->assertEquals(['London', 'Bristol'], $freshUser->addresses->pluck('city')->all());
- }
-
- public function testEmbedsManyDuplicate()
- {
- $user = User::create(['name' => 'John Doe']);
- $address = new Address(['city' => 'London']);
- $user->addresses()->save($address);
- $user->addresses()->save($address);
- $this->assertEquals(1, $user->addresses->count());
- $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
-
- $user = User::find($user->id);
- $this->assertEquals(1, $user->addresses->count());
-
- $address->city = 'Paris';
- $user->addresses()->save($address);
- $this->assertEquals(1, $user->addresses->count());
- $this->assertEquals(['Paris'], $user->addresses->pluck('city')->all());
-
- $user->addresses()->create(['_id' => $address->_id, 'city' => 'Bruxelles']);
- $this->assertEquals(1, $user->addresses->count());
- $this->assertEquals(['Bruxelles'], $user->addresses->pluck('city')->all());
- }
-
- public function testEmbedsManyCreate()
- {
- $user = User::create([]);
- $address = $user->addresses()->create(['city' => 'Bruxelles']);
- $this->assertInstanceOf(Address::class, $address);
- $this->assertIsString($address->_id);
- $this->assertEquals(['Bruxelles'], $user->addresses->pluck('city')->all());
-
- $raw = $address->getAttributes();
- $this->assertInstanceOf(ObjectId::class, $raw['_id']);
-
- $freshUser = User::find($user->id);
- $this->assertEquals(['Bruxelles'], $freshUser->addresses->pluck('city')->all());
-
- $user = User::create([]);
- $address = $user->addresses()->create(['_id' => '', 'city' => 'Bruxelles']);
- $this->assertIsString($address->_id);
-
- $raw = $address->getAttributes();
- $this->assertInstanceOf(ObjectId::class, $raw['_id']);
- }
-
- public function testEmbedsManyCreateMany()
- {
- $user = User::create([]);
- list($bruxelles, $paris) = $user->addresses()->createMany([['city' => 'Bruxelles'], ['city' => 'Paris']]);
- $this->assertInstanceOf(Address::class, $bruxelles);
- $this->assertEquals('Bruxelles', $bruxelles->city);
- $this->assertEquals(['Bruxelles', 'Paris'], $user->addresses->pluck('city')->all());
-
- $freshUser = User::find($user->id);
- $this->assertEquals(['Bruxelles', 'Paris'], $freshUser->addresses->pluck('city')->all());
- }
-
- public function testEmbedsManyDestroy()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->saveMany([
- new Address(['city' => 'London']),
- new Address(['city' => 'Bristol']),
- new Address(['city' => 'Bruxelles']),
- ]);
-
- $address = $user->addresses->first();
-
- $address->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($address), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.deleting: ' . get_class($address), Mockery::type(Address::class))
- ->andReturn(true);
- $events->shouldReceive('dispatch')
- ->once()
- ->with('eloquent.deleted: ' . get_class($address), Mockery::type(Address::class));
-
- $user->addresses()->destroy($address->_id);
- $this->assertEquals(['Bristol', 'Bruxelles'], $user->addresses->pluck('city')->all());
-
- $address->unsetEventDispatcher();
-
- $address = $user->addresses->first();
- $user->addresses()->destroy($address);
- $this->assertEquals(['Bruxelles'], $user->addresses->pluck('city')->all());
-
- $user->addresses()->create(['city' => 'Paris']);
- $user->addresses()->create(['city' => 'San Francisco']);
-
- $freshUser = User::find($user->id);
- $this->assertEquals(['Bruxelles', 'Paris', 'San Francisco'], $freshUser->addresses->pluck('city')->all());
-
- $ids = $user->addresses->pluck('_id');
- $user->addresses()->destroy($ids);
- $this->assertEquals([], $user->addresses->pluck('city')->all());
-
- $freshUser = User::find($user->id);
- $this->assertEquals([], $freshUser->addresses->pluck('city')->all());
-
- list($london, $bristol, $bruxelles) = $user->addresses()->saveMany([
- new Address(['city' => 'London']),
- new Address(['city' => 'Bristol']),
- new Address(['city' => 'Bruxelles']),
- ]);
- $user->addresses()->destroy([$london, $bruxelles]);
- $this->assertEquals(['Bristol'], $user->addresses->pluck('city')->all());
- }
-
- public function testEmbedsManyDelete()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->saveMany([
- new Address(['city' => 'London']),
- new Address(['city' => 'Bristol']),
- new Address(['city' => 'Bruxelles']),
- ]);
-
- $address = $user->addresses->first();
-
- $address->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($address), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.deleting: ' . get_class($address), Mockery::type(Address::class))
- ->andReturn(true);
- $events->shouldReceive('dispatch')
- ->once()
- ->with('eloquent.deleted: ' . get_class($address), Mockery::type(Address::class));
-
- $address->delete();
-
- $this->assertEquals(2, $user->addresses()->count());
- $this->assertEquals(2, $user->addresses->count());
-
- $address->unsetEventDispatcher();
-
- $address = $user->addresses->first();
- $address->delete();
-
- $user = User::where('name', 'John Doe')->first();
- $this->assertEquals(1, $user->addresses()->count());
- $this->assertEquals(1, $user->addresses->count());
- }
-
- public function testEmbedsManyDissociate()
- {
- $user = User::create([]);
- $cordoba = $user->addresses()->create(['city' => 'Cordoba']);
-
- $user->addresses()->dissociate($cordoba->id);
-
- $freshUser = User::find($user->id);
- $this->assertEquals(0, $user->addresses->count());
- $this->assertEquals(1, $freshUser->addresses->count());
- }
-
- public function testEmbedsManyAliases()
- {
- $user = User::create(['name' => 'John Doe']);
- $address = new Address(['city' => 'London']);
-
- $address = $user->addresses()->attach($address);
- $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
-
- $user->addresses()->detach($address);
- $this->assertEquals([], $user->addresses->pluck('city')->all());
- }
-
- public function testEmbedsManyCreatingEventReturnsFalse()
- {
- $user = User::create(['name' => 'John Doe']);
- $address = new Address(['city' => 'London']);
-
- $address->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($address), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.saving: ' . get_class($address), $address)
- ->andReturn(true);
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.creating: ' . get_class($address), $address)
- ->andReturn(false);
-
- $this->assertFalse($user->addresses()->save($address));
- $address->unsetEventDispatcher();
- }
-
- public function testEmbedsManySavingEventReturnsFalse()
- {
- $user = User::create(['name' => 'John Doe']);
- $address = new Address(['city' => 'Paris']);
- $address->exists = true;
-
- $address->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($address), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.saving: ' . get_class($address), $address)
- ->andReturn(false);
-
- $this->assertFalse($user->addresses()->save($address));
- $address->unsetEventDispatcher();
- }
-
- public function testEmbedsManyUpdatingEventReturnsFalse()
- {
- $user = User::create(['name' => 'John Doe']);
- $address = new Address(['city' => 'New York']);
- $user->addresses()->save($address);
-
- $address->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($address), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.saving: ' . get_class($address), $address)
- ->andReturn(true);
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.updating: ' . get_class($address), $address)
- ->andReturn(false);
-
- $address->city = 'Warsaw';
-
- $this->assertFalse($user->addresses()->save($address));
- $address->unsetEventDispatcher();
- }
-
- public function testEmbedsManyDeletingEventReturnsFalse()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->save(new Address(['city' => 'New York']));
-
- $address = $user->addresses->first();
-
- $address->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($address), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.deleting: ' . get_class($address), Mockery::mustBe($address))
- ->andReturn(false);
-
- $this->assertEquals(0, $user->addresses()->destroy($address));
- $this->assertEquals(['New York'], $user->addresses->pluck('city')->all());
-
- $address->unsetEventDispatcher();
- }
-
- public function testEmbedsManyFindOrContains()
- {
- $user = User::create(['name' => 'John Doe']);
- $address1 = $user->addresses()->save(new Address(['city' => 'New York']));
- $address2 = $user->addresses()->save(new Address(['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'));
- }
-
- public function testEmbedsManyEagerLoading()
- {
- $user1 = User::create(['name' => 'John Doe']);
- $user1->addresses()->save(new Address(['city' => 'New York']));
- $user1->addresses()->save(new Address(['city' => 'Paris']));
-
- $user2 = User::create(['name' => 'Jane Doe']);
- $user2->addresses()->save(new Address(['city' => 'Berlin']));
- $user2->addresses()->save(new Address(['city' => 'Paris']));
-
- $user = User::find($user1->id);
- $relations = $user->getRelations();
- $this->assertArrayNotHasKey('addresses', $relations);
- $this->assertArrayHasKey('addresses', $user->toArray());
- $this->assertIsArray($user->toArray()['addresses']);
-
- $user = User::with('addresses')->get()->first();
- $relations = $user->getRelations();
- $this->assertArrayHasKey('addresses', $relations);
- $this->assertEquals(2, $relations['addresses']->count());
- $this->assertArrayHasKey('addresses', $user->toArray());
- $this->assertIsArray($user->toArray()['addresses']);
- }
-
- public function testEmbedsManyDeleteAll()
- {
- $user1 = User::create(['name' => 'John Doe']);
- $user1->addresses()->save(new Address(['city' => 'New York']));
- $user1->addresses()->save(new Address(['city' => 'Paris']));
-
- $user2 = User::create(['name' => 'Jane Doe']);
- $user2->addresses()->save(new Address(['city' => 'Berlin']));
- $user2->addresses()->save(new Address(['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());
- }
-
- public function testEmbedsManyCollectionMethods()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->save(new Address([
- 'city' => 'Paris',
- 'country' => 'France',
- 'visited' => 4,
- 'created_at' => new DateTime('3 days ago'),
- ]));
- $user->addresses()->save(new Address([
- 'city' => 'Bruges',
- 'country' => 'Belgium',
- 'visited' => 7,
- 'created_at' => new DateTime('5 days ago'),
- ]));
- $user->addresses()->save(new Address([
- 'city' => 'Brussels',
- 'country' => 'Belgium',
- 'visited' => 2,
- 'created_at' => new DateTime('4 days ago'),
- ]));
- $user->addresses()->save(new Address([
- 'city' => 'Ghent',
- 'country' => 'Belgium',
- 'visited' => 13,
- 'created_at' => new DateTime('2 days ago'),
- ]));
-
- $this->assertEquals(['Paris', 'Bruges', 'Brussels', 'Ghent'], $user->addresses()->pluck('city')->all());
- $this->assertEquals(['Bruges', 'Brussels', 'Ghent', 'Paris'], $user->addresses()
- ->sortBy('city')
- ->pluck('city')
- ->all());
- $this->assertEquals([], $user->addresses()->where('city', 'New York')->pluck('city')->all());
- $this->assertEquals(['Bruges', 'Brussels', 'Ghent'], $user->addresses()
- ->where('country', 'Belgium')
- ->pluck('city')
- ->all());
- $this->assertEquals(['Bruges', 'Brussels', 'Ghent'], $user->addresses()
- ->where('country', 'Belgium')
- ->sortBy('city')
- ->pluck('city')
- ->all());
-
- $results = $user->addresses->first();
- $this->assertInstanceOf(Address::class, $results);
-
- $results = $user->addresses()->where('country', 'Belgium');
- $this->assertInstanceOf(Collection::class, $results);
- $this->assertEquals(3, $results->count());
-
- $results = $user->addresses()->whereIn('visited', [7, 13]);
- $this->assertEquals(2, $results->count());
- }
-
- public function testEmbedsOne()
- {
- $user = User::create(['name' => 'John Doe']);
- $father = new User(['name' => 'Mark Doe']);
-
- $father->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($father), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.saving: ' . get_class($father), $father)
- ->andReturn(true);
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.creating: ' . get_class($father), $father)
- ->andReturn(true);
- $events->shouldReceive('dispatch')->once()->with('eloquent.created: ' . get_class($father), $father);
- $events->shouldReceive('dispatch')->once()->with('eloquent.saved: ' . get_class($father), $father);
-
- $father = $user->father()->save($father);
- $father->unsetEventDispatcher();
-
- $this->assertNotNull($user->father);
- $this->assertEquals('Mark Doe', $user->father->name);
- $this->assertInstanceOf(DateTime::class, $father->created_at);
- $this->assertInstanceOf(DateTime::class, $father->updated_at);
- $this->assertNotNull($father->_id);
- $this->assertIsString($father->_id);
-
- $raw = $father->getAttributes();
- $this->assertInstanceOf(ObjectId::class, $raw['_id']);
-
- $father->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($father), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.saving: ' . get_class($father), $father)
- ->andReturn(true);
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.updating: ' . get_class($father), $father)
- ->andReturn(true);
- $events->shouldReceive('dispatch')->once()->with('eloquent.updated: ' . get_class($father), $father);
- $events->shouldReceive('dispatch')->once()->with('eloquent.saved: ' . get_class($father), $father);
-
- $father->name = 'Tom Doe';
- $user->father()->save($father);
- $father->unsetEventDispatcher();
-
- $this->assertNotNull($user->father);
- $this->assertEquals('Tom Doe', $user->father->name);
-
- $father = new User(['name' => 'Jim Doe']);
-
- $father->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($father), Mockery::any());
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.saving: ' . get_class($father), $father)
- ->andReturn(true);
- $events->shouldReceive('until')
- ->once()
- ->with('eloquent.creating: ' . get_class($father), $father)
- ->andReturn(true);
- $events->shouldReceive('dispatch')->once()->with('eloquent.created: ' . get_class($father), $father);
- $events->shouldReceive('dispatch')->once()->with('eloquent.saved: ' . get_class($father), $father);
-
- $father = $user->father()->save($father);
- $father->unsetEventDispatcher();
-
- $this->assertNotNull($user->father);
- $this->assertEquals('Jim Doe', $user->father->name);
- }
-
- public function testEmbedsOneAssociate()
- {
- $user = User::create(['name' => 'John Doe']);
- $father = new User(['name' => 'Mark Doe']);
-
- $father->setEventDispatcher($events = Mockery::mock(Dispatcher::class));
- $events->shouldReceive('dispatch')->with('eloquent.retrieved: ' . get_class($father), Mockery::any());
- $events->shouldReceive('until')->times(0)->with('eloquent.saving: ' . get_class($father), $father);
-
- $father = $user->father()->associate($father);
- $father->unsetEventDispatcher();
-
- $this->assertNotNull($user->father);
- $this->assertEquals('Mark Doe', $user->father->name);
- }
-
- public function testEmbedsOneNullAssociation()
- {
- $user = User::create();
- $this->assertNull($user->father);
- }
-
- public function testEmbedsOneDelete()
- {
- $user = User::create(['name' => 'John Doe']);
- $father = $user->father()->save(new User(['name' => 'Mark Doe']));
-
- $user->father()->delete();
- $this->assertNull($user->father);
- }
-
- public function testEmbedsManyToArray()
- {
- /** @var User $user */
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->save(new Address(['city' => 'New York']));
- $user->addresses()->save(new Address(['city' => 'Paris']));
- $user->addresses()->save(new Address(['city' => 'Brussels']));
-
- $array = $user->toArray();
- $this->assertArrayHasKey('addresses', $array);
- $this->assertIsArray($array['addresses']);
- }
-
- public function testEmbeddedSave()
- {
- /** @var User $user */
- $user = User::create(['name' => 'John Doe']);
- /** @var \Address $address */
- $address = $user->addresses()->create(['city' => 'New York']);
- $father = $user->father()->create(['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);
-
- $address = $user->addresses()->first();
- $father = $user->father;
-
- $address->city = 'Ghent';
- $address->save();
-
- $father->name = 'Mark Doe';
- $father->save();
-
- $this->assertEquals('Ghent', $user->addresses->first()->city);
- $this->assertEquals('Mark Doe', $user->father->name);
-
- $user = User::where('name', 'John Doe')->first();
- $this->assertEquals('Ghent', $user->addresses->first()->city);
- $this->assertEquals('Mark Doe', $user->father->name);
- }
-
- public function testNestedEmbedsOne()
- {
- $user = User::create(['name' => 'John Doe']);
- $father = $user->father()->create(['name' => 'Mark Doe']);
- $grandfather = $father->father()->create(['name' => 'Steve Doe']);
- $greatgrandfather = $grandfather->father()->create(['name' => 'Tom Doe']);
-
- $user->name = 'Tim Doe';
- $user->save();
-
- $father->name = 'Sven Doe';
- $father->save();
-
- $greatgrandfather->name = 'Ron Doe';
- $greatgrandfather->save();
-
- $this->assertEquals('Tim Doe', $user->name);
- $this->assertEquals('Sven Doe', $user->father->name);
- $this->assertEquals('Steve Doe', $user->father->father->name);
- $this->assertEquals('Ron Doe', $user->father->father->father->name);
-
- $user = User::where('name', 'Tim Doe')->first();
- $this->assertEquals('Tim Doe', $user->name);
- $this->assertEquals('Sven Doe', $user->father->name);
- $this->assertEquals('Steve Doe', $user->father->father->name);
- $this->assertEquals('Ron Doe', $user->father->father->father->name);
- }
-
- public function testNestedEmbedsMany()
- {
- $user = User::create(['name' => 'John Doe']);
- $country1 = $user->addresses()->create(['country' => 'France']);
- $country2 = $user->addresses()->create(['country' => 'Belgium']);
- $city1 = $country1->addresses()->create(['city' => 'Paris']);
- $city2 = $country2->addresses()->create(['city' => 'Ghent']);
- $city3 = $country2->addresses()->create(['city' => 'Brussels']);
-
- $city3->city = 'Bruges';
- $city3->save();
-
- $this->assertEquals(2, $user->addresses()->count());
- $this->assertEquals(1, $user->addresses()->first()->addresses()->count());
- $this->assertEquals(2, $user->addresses()->last()->addresses()->count());
-
- $user = User::where('name', 'John Doe')->first();
- $this->assertEquals(2, $user->addresses()->count());
- $this->assertEquals(1, $user->addresses()->first()->addresses()->count());
- $this->assertEquals(2, $user->addresses()->last()->addresses()->count());
- }
-
- public function testNestedMixedEmbeds()
- {
- $user = User::create(['name' => 'John Doe']);
- $father = $user->father()->create(['name' => 'Mark Doe']);
- $country1 = $father->addresses()->create(['country' => 'France']);
- $country2 = $father->addresses()->create(['country' => 'Belgium']);
-
- $country2->country = 'England';
- $country2->save();
-
- $father->name = 'Steve Doe';
- $father->save();
-
- $this->assertEquals('France', $user->father->addresses()->first()->country);
- $this->assertEquals('England', $user->father->addresses()->last()->country);
- $this->assertEquals('Steve Doe', $user->father->name);
-
- $user = User::where('name', 'John Doe')->first();
- $this->assertEquals('France', $user->father->addresses()->first()->country);
- $this->assertEquals('England', $user->father->addresses()->last()->country);
- $this->assertEquals('Steve Doe', $user->father->name);
- }
-
- public function testNestedEmbedsOneDelete()
- {
- $user = User::create(['name' => 'John Doe']);
- $father = $user->father()->create(['name' => 'Mark Doe']);
- $grandfather = $father->father()->create(['name' => 'Steve Doe']);
- $greatgrandfather = $grandfather->father()->create(['name' => 'Tom Doe']);
-
- $grandfather->delete();
-
- $this->assertNull($user->father->father);
-
- $user = User::where(['name' => 'John Doe'])->first();
- $this->assertNull($user->father->father);
- }
-
- public function testNestedEmbedsManyDelete()
- {
- $user = User::create(['name' => 'John Doe']);
- $country = $user->addresses()->create(['country' => 'France']);
- $city1 = $country->addresses()->create(['city' => 'Paris']);
- $city2 = $country->addresses()->create(['city' => 'Nice']);
- $city3 = $country->addresses()->create(['city' => 'Lyon']);
-
- $city2->delete();
-
- $this->assertEquals(2, $user->addresses()->first()->addresses()->count());
- $this->assertEquals('Lyon', $country->addresses()->last()->city);
-
- $user = User::where('name', 'John Doe')->first();
- $this->assertEquals(2, $user->addresses()->first()->addresses()->count());
- $this->assertEquals('Lyon', $country->addresses()->last()->city);
- }
-
- public function testNestedMixedEmbedsDelete()
- {
- $user = User::create(['name' => 'John Doe']);
- $father = $user->father()->create(['name' => 'Mark Doe']);
- $country1 = $father->addresses()->create(['country' => 'France']);
- $country2 = $father->addresses()->create(['country' => 'Belgium']);
-
- $country1->delete();
-
- $this->assertEquals(1, $user->father->addresses()->count());
- $this->assertEquals('Belgium', $user->father->addresses()->last()->country);
-
- $user = User::where('name', 'John Doe')->first();
- $this->assertEquals(1, $user->father->addresses()->count());
- $this->assertEquals('Belgium', $user->father->addresses()->last()->country);
- }
-
- public function testDoubleAssociate()
- {
- $user = User::create(['name' => 'John Doe']);
- $address = new Address(['city' => 'Paris']);
-
- $user->addresses()->associate($address);
- $user->addresses()->associate($address);
- $address = $user->addresses()->first();
- $user->addresses()->associate($address);
- $this->assertEquals(1, $user->addresses()->count());
-
- $user = User::where('name', 'John Doe')->first();
- $user->addresses()->associate($address);
- $this->assertEquals(1, $user->addresses()->count());
-
- $user->save();
- $user->addresses()->associate($address);
- $this->assertEquals(1, $user->addresses()->count());
- }
-
- public function testSaveEmptyModel()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->save(new Address);
- $this->assertNotNull($user->addresses);
- $this->assertEquals(1, $user->addresses()->count());
- }
-
- public function testIncrementEmbedded()
- {
- $user = User::create(['name' => 'John Doe']);
- $address = $user->addresses()->create(['city' => 'New York', 'visited' => 5]);
-
- $address->increment('visited');
- $this->assertEquals(6, $address->visited);
- $this->assertEquals(6, $user->addresses()->first()->visited);
-
- $user = User::where('name', 'John Doe')->first();
- $this->assertEquals(6, $user->addresses()->first()->visited);
-
- $user = User::where('name', 'John Doe')->first();
- $address = $user->addresses()->first();
-
- $address->decrement('visited');
- $this->assertEquals(5, $address->visited);
- $this->assertEquals(5, $user->addresses()->first()->visited);
-
- $user = User::where('name', 'John Doe')->first();
- $this->assertEquals(5, $user->addresses()->first()->visited);
- }
-
- public function testPaginateEmbedsMany()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->save(new Address(['city' => 'New York']));
- $user->addresses()->save(new Address(['city' => 'Paris']));
- $user->addresses()->save(new Address(['city' => 'Brussels']));
-
- $results = $user->addresses()->paginate(2);
- $this->assertEquals(2, $results->count());
- $this->assertEquals(3, $results->total());
- }
-
- public function testGetQueueableRelationsEmbedsMany()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->addresses()->save(new Address(['city' => 'New York']));
- $user->addresses()->save(new Address(['city' => 'Paris']));
-
- $this->assertEquals(['addresses'], $user->getQueueableRelations());
- $this->assertEquals([], $user->addresses->getQueueableRelations());
- }
-
- public function testGetQueueableRelationsEmbedsOne()
- {
- $user = User::create(['name' => 'John Doe']);
- $user->father()->save(new User(['name' => 'Mark Doe']));
-
- $this->assertEquals(['father'], $user->getQueueableRelations());
- $this->assertEquals([], $user->father->getQueueableRelations());
- }
-}
diff --git a/tests/QueryBuilderTest.php b/tests/QueryBuilderTest.php
index 6588be159..8c737d859 100644
--- a/tests/QueryBuilderTest.php
+++ b/tests/QueryBuilderTest.php
@@ -639,27 +639,6 @@ public function testOperators()
$results = DB::collection('users')->where('name', 'not regexp', '/.*doe/i')->get();
$this->assertCount(1, $results);
-
- DB::collection('users')->insert([
- [
- 'name' => 'John Doe',
- 'addresses' => [
- ['city' => 'Ghent'],
- ['city' => 'Paris'],
- ],
- ],
- [
- 'name' => 'Jane Doe',
- 'addresses' => [
- ['city' => 'Brussels'],
- ['city' => 'Paris'],
- ],
- ],
- ]);
-
- $users = DB::collection('users')->where('addresses', 'elemMatch', ['city' => 'Brussels'])->get();
- $this->assertCount(1, $users);
- $this->assertEquals('Jane Doe', $users[0]['name']);
}
public function testIncrement()
diff --git a/tests/RelationsTest.php b/tests/RelationsTest.php
index 86065aac3..31692b0fe 100644
--- a/tests/RelationsTest.php
+++ b/tests/RelationsTest.php
@@ -337,8 +337,6 @@ public function testBelongsToManyCustom(): void
$this->assertArrayHasKey('groups', $user->getAttributes());
// Assert they are attached
- $this->assertContains($group->_id, $user->groups->pluck('_id')->toArray());
- $this->assertContains($user->_id, $group->users->pluck('_id')->toArray());
$this->assertEquals($group->_id, $user->groups()->first()->_id);
$this->assertEquals($user->_id, $group->users()->first()->_id);
}
diff --git a/tests/models/Address.php b/tests/models/Address.php
index 9d094cfcd..d59f946ea 100644
--- a/tests/models/Address.php
+++ b/tests/models/Address.php
@@ -2,15 +2,9 @@
declare(strict_types=1);
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
-use Jenssegers\Mongodb\Relations\EmbedsMany;
class Address extends Eloquent
{
protected $connection = 'mongodb';
protected static $unguarded = true;
-
- public function addresses(): EmbedsMany
- {
- return $this->embedsMany('Address');
- }
}
diff --git a/tests/models/User.php b/tests/models/User.php
index 1217af762..93dc3e52a 100644
--- a/tests/models/User.php
+++ b/tests/models/User.php
@@ -67,16 +67,6 @@ public function photos()
return $this->morphMany('Photo', 'imageable');
}
- public function addresses()
- {
- return $this->embedsMany('Address');
- }
-
- public function father()
- {
- return $this->embedsOne('User');
- }
-
public function getDateFormat()
{
return 'l jS \of F Y h:i:s A';