Skip to content

[4.x] Remove embeds relations #1982

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
191 changes: 5 additions & 186 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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**

Expand Down Expand Up @@ -712,10 +710,6 @@ The only available relationships are:
- belongsTo
- belongsToMany

The MongoDB-specific relationships are:
- embedsOne
- embedsMany

Here is a small example:

```php
Expand Down Expand Up @@ -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
-------------

Expand Down Expand Up @@ -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)
1 change: 0 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
</testsuite>
<testsuite name="relations">
<file>tests/RelationsTest.php</file>
<file>tests/EmbeddedRelationsTest.php</file>
</testsuite>
<testsuite name="mysqlrelations">
<file>tests/RelationsTest.php</file>
Expand Down
64 changes: 0 additions & 64 deletions src/Jenssegers/Mongodb/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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();
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand Down
Loading