Skip to content

Commit

Permalink
Merge pull request #50 from scrnhq/hotfix/nullable-relationships
Browse files Browse the repository at this point in the history
Properly set relationships to null
  • Loading branch information
robertvansteen authored Jul 18, 2018
2 parents 7435117 + 2f9c2a2 commit 888f459
Show file tree
Hide file tree
Showing 12 changed files with 172 additions and 3 deletions.
18 changes: 16 additions & 2 deletions src/Eloquent/Concerns/InteractsWithRelations.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ protected function fillConnections(array $connections)
*/
protected function connectBelongsToRelation(Relations\BelongsTo $relation, $id)
{
if (! $id) {
$relation->associate(null);

return;
}

$model = $relation->getRelated()->findOrFail($id);
$relation->associate($model);
}
Expand All @@ -104,9 +110,17 @@ protected function fillBelongsToRelation(Relations\BelongsTo $relation, $attribu
*/
protected function connectHasOneRelation(Relations\HasOne $relation, $id)
{
$model = $relation->getRelated()->findOrFail($id);
if (! $id) {
if ($related = $relation->getResults()) {
$related->setAttribute($relation->getForeignKeyName(), null);
$related->save();
}

$this->transactionQueue[] = function () use ($model, $relation) {
return;
}

$this->transactionQueue[] = function () use ($id, $relation) {
$model = $relation->getRelated()->findOrFail($id);
$model->setAttribute($relation->getForeignKeyName(), $relation->getParentKey());
$model->save();
};
Expand Down
49 changes: 49 additions & 0 deletions tests/Feature/CreateMutationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,30 @@ public function it_lets_you_save_a_has_one_relationship()
$this->assertDatabaseHas('phones', ['user_id' => '2']);
}

/** @test */
public function it_lets_you_set_a_has_one_relationship_to_null()
{
$user = factory(Models\User::class)->create();
$this->actingAs($user);

$query = '
mutation {
createUser(input: {
email: "jane.doe@example.com",
name: "Jane Doe",
password: "secret",
phoneId: null,
}) {
id
}
}
';

$response = $this->json('GET', '/graphql', ['query' => $query]);
$response->assertJsonFragment(['id']);
$this->assertDatabaseHas('users', ['email' => 'jane.doe@example.com']);
}

/** @test */
public function it_lets_you_create_a_belongs_to_relationship()
{
Expand Down Expand Up @@ -270,4 +294,29 @@ public function it_lets_you_do_deep_nested_create_mutations()
$this->assertDatabaseHas('comments', ['body' => 'First!', 'article_id' => '1']);
$this->assertDatabaseHas('comments', ['body' => 'Great post!', 'article_id' => '1']);
}

/** @test */
public function it_lets_you_reset_a_belongs_to_relationship()
{
$user = factory(Models\User::class)->create();
$this->actingAs($user);

$query = '
mutation {
createArticle(input: {
userId: "'.$user->id.'",
categoryId: null,
title: "Hello World!"
slug: "hello-world"
content: "Lorem ipsum"
}) {
id
}
}
';

$response = $this->json('GET', '/graphql', ['query' => $query]);
$response->assertJsonFragment(['id']);
$this->assertDatabaseHas('articles', ['title' => 'Hello World!', 'category_id' => null]);
}
}
21 changes: 21 additions & 0 deletions tests/Feature/UpdateMutationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,25 @@ public function it_can_set_policy_for_updating_an_attribute()
$response->assertJsonFragment(['updateUser' => null]);
$this->assertDatabaseMissing('users', ['type' => 'admin']);
}

/** @test */
public function it_lets_you_reset_a_has_one_relationship()
{
$phone = factory(Models\Phone::class)->create();
$this->actingAs($phone->user);

$query = '
mutation {
updateUser(id: "'.$phone->user->id.'", input: {
phoneId: null,
}) {
id
}
}
';

$response = $this->json('GET', '/graphql', ['query' => $query]);
$response->assertJsonFragment(['id']);
$this->assertDatabaseHas('phones', ['user_id' => null]);
}
}
1 change: 1 addition & 0 deletions tests/FeatureTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ protected function setUp()
Stubs\BakeryModels\PhoneBakery::class,
Stubs\BakeryModels\CommentBakery::class,
Stubs\BakeryModels\RoleBakery::class,
Stubs\BakeryModels\CategoryBakery::class,
]);
}

Expand Down
5 changes: 5 additions & 0 deletions tests/Models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,9 @@ public function comments()
{
return $this->hasMany(Comment::class);
}

public function category()
{
return $this->belongsTo(Category::class);
}
}
19 changes: 19 additions & 0 deletions tests/Models/Category.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Bakery\Tests\Models;

use Bakery\Eloquent\Mutable;
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
use Mutable;

protected $casts = [
'id' => 'string',
];

protected $fillable = [
'name',
];
}
1 change: 1 addition & 0 deletions tests/Stubs/BakeryModels/ArticleBakery.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function relations(): array
{
return [
'user' => Bakery::type('User'),
'category' => Bakery::type('Category'),
'comments' => Bakery::nonNull(Bakery::listOf(Bakery::type('Comment'))),
];
}
Expand Down
26 changes: 26 additions & 0 deletions tests/Stubs/BakeryModels/CategoryBakery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Bakery\Tests\Stubs\BakeryModels;

use Bakery\Tests\Models\Category;
use GraphQL\Type\Definition\Type;
use Bakery\Eloquent\Introspectable;

class CategoryBakery
{
use Introspectable;

public static $model = Category::class;

public function fields(): array
{
return [
'name' => Type::nonNull(Type::string()),
];
}

public function relations(): array
{
return [];
}
}
5 changes: 5 additions & 0 deletions tests/Stubs/Policies/ArticlePolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public function setUser(): bool
return true;
}

public function setCategory(): bool
{
return true;
}

public function createComments(): bool
{
return true;
Expand Down
23 changes: 23 additions & 0 deletions tests/migrations/0000_00_00_000000_create_categories_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Migrations\Migration;

class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::create('categories', function ($table) {
$table->increments('id');
$table->string('name');
});
}

public function down()
{
Schema::drop('categories');
}
}
5 changes: 5 additions & 0 deletions tests/migrations/0000_00_00_000001_create_articles_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ public function up()
$table->string('slug');
$table->text('content');
$table->timestamp('published_at')->nullable();
$table->unsignedInteger('category_id')->nullable();
$table->unsignedInteger('user_id');
$table->timestamps();

$table->foreign('category_id')
->references('id')->on('categories')
->onDelete('set null');

$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
Expand Down
2 changes: 1 addition & 1 deletion tests/migrations/0000_00_00_000002_create_phones_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function up()
Schema::create('phones', function (Blueprint $table) {
$table->increments('id');
$table->string('number')->unique();
$table->unsignedInteger('user_id');
$table->unsignedInteger('user_id')->nullable();
$table->timestamps();

$table->foreign('user_id')
Expand Down

0 comments on commit 888f459

Please sign in to comment.