Skip to content

Commit e041c9a

Browse files
authored
Fixed problem with nullable relations. (#29)
1 parent 4ae16d2 commit e041c9a

File tree

3 files changed

+92
-27
lines changed

3 files changed

+92
-27
lines changed

Diff for: src/Relation/Traits/FieldTrait.php

+18-17
Original file line numberDiff line numberDiff line change
@@ -55,30 +55,31 @@ protected function ensureField(Entity $target, string $name, Field $outer, bool
5555
$outer->setReferenced(true);
5656

5757
if ($target->getFields()->has($name)) {
58-
// field already exists and defined by the user
59-
return;
60-
}
58+
// field already exists and defined previously or by the user
59+
$field = $target->getFields()->get($name);
60+
} else {
61+
$field = new Field();
62+
$field->setColumn($name);
63+
$field->setTypecast($outer->getTypecast());
6164

62-
$field = new Field();
63-
$field->setColumn($name);
64-
$field->setTypecast($outer->getTypecast());
65+
switch ($outer->getType()) {
66+
case 'primary':
67+
$field->setType('int');
68+
break;
69+
case 'bigPrimary':
70+
$field->setType('bigint');
71+
break;
72+
default:
73+
$field->setType($outer->getType());
74+
}
6575

66-
switch ($outer->getType()) {
67-
case 'primary':
68-
$field->setType('int');
69-
break;
70-
case 'bigPrimary':
71-
$field->setType('bigint');
72-
break;
73-
default:
74-
$field->setType($outer->getType());
76+
$target->getFields()->set($name, $field);
7577
}
7678

79+
// If on of relations requires nullable type then making it nullable
7780
if ($nullable) {
7881
$field->getOptions()->set(Column::OPT_NULLABLE, true);
7982
}
80-
81-
$target->getFields()->set($name, $field);
8283
}
8384

8485
/**

Diff for: src/Relation/Traits/MorphTrait.php

+11-10
Original file line numberDiff line numberDiff line change
@@ -73,24 +73,25 @@ protected function findOuterKey(Registry $registry, string $interface): array
7373
/**
7474
* @param Entity $target
7575
* @param string $name
76-
* @param int $lenght
76+
* @param int $length
7777
* @param bool $nullable
7878
*/
79-
protected function ensureMorphField(Entity $target, string $name, int $lenght, bool $nullable = false): void
79+
protected function ensureMorphField(Entity $target, string $name, int $length, bool $nullable = false): void
8080
{
8181
if ($target->getFields()->has($name)) {
82-
// field already exists and defined by the user
83-
return;
84-
}
82+
// field already exists and defined previously or by the user
83+
$field = $target->getFields()->get($name);
84+
} else {
85+
$field = new Field();
86+
$field->setColumn($name);
87+
$field->setType(sprintf('string(%s)', $length));
8588

86-
$field = new Field();
87-
$field->setColumn($name);
88-
$field->setType(sprintf('string(%s)', $lenght));
89+
$target->getFields()->set($name, $field);
90+
}
8991

92+
// If on of relations requires nullable type then making it nullable
9093
if ($nullable) {
9194
$field->getOptions()->set(Column::OPT_NULLABLE, true);
9295
}
93-
94-
$target->getFields()->set($name, $field);
9596
}
9697
}

Diff for: tests/Schema/Relation/BelongsToRelationTest.php

+63
Original file line numberDiff line numberDiff line change
@@ -251,4 +251,67 @@ public function testInverseToHasMany(): void
251251
$schema['author'][Schema::RELATIONS]['post'][Relation::SCHEMA][Relation::INNER_KEY]
252252
);
253253
}
254+
255+
public function testRelatedFieldShouldBeCreated()
256+
{
257+
$e = Post::define();
258+
$u = Author::define();
259+
260+
$e->getRelations()->get('author')->setInverse('post', 'hasMany');
261+
262+
$r = new Registry($this->dbal);
263+
$r->register($e)->linkTable($e, 'default', 'post');
264+
$r->register($u)->linkTable($u, 'default', 'author');
265+
266+
(new Compiler())->compile($r, [
267+
new GenerateRelations(['belongsTo' => new BelongsTo(), 'hasMany' => new HasMany()]),
268+
]);
269+
270+
$this->assertTrue($e->getFields()->has('author_id'));
271+
$this->assertFalse($e->getFields()->get('author_id')->getOptions()->has('nullable'));
272+
}
273+
274+
public function testRelatedFieldShouldBeNullableIfBelongsToHasNullableOption()
275+
{
276+
$e = Post::define();
277+
$u = Author::define();
278+
279+
$e->getRelations()->get('author')->setInverse('post', 'hasMany')->getOptions()->set('nullable', true);
280+
281+
$r = new Registry($this->dbal);
282+
$r->register($e)->linkTable($e, 'default', 'post');
283+
$r->register($u)->linkTable($u, 'default', 'author');
284+
285+
(new Compiler())->compile($r, [
286+
new GenerateRelations(['belongsTo' => new BelongsTo(), 'hasMany' => new HasMany()]),
287+
]);
288+
289+
$this->assertTrue($e->getFields()->has('author_id'));
290+
$this->assertTrue($e->getFields()->get('author_id')->getOptions()->get('nullable'));
291+
}
292+
293+
public function testRelatedFieldShouldBeNullableIHasManyHasNullableOption()
294+
{
295+
$e = Post::define();
296+
$u = Author::define();
297+
298+
$hasMany = (new \Cycle\Schema\Definition\Relation())
299+
->setTarget(Post::class)
300+
->setType('hasMany')
301+
->setInverse('author', 'belongsTo');
302+
$hasMany->getOptions()->set('nullable', true);
303+
$u->getRelations()->set('posts', $hasMany);
304+
$e->getRelations()->get('author')->setInverse('post', 'hasMany');
305+
306+
$r = new Registry($this->dbal);
307+
$r->register($e)->linkTable($e, 'default', 'post');
308+
$r->register($u)->linkTable($u, 'default', 'author');
309+
310+
(new Compiler())->compile($r, [
311+
new GenerateRelations(['belongsTo' => new BelongsTo(), 'hasMany' => new HasMany()]),
312+
]);
313+
314+
$this->assertTrue($e->getFields()->has('author_id'));
315+
$this->assertTrue($e->getFields()->get('author_id')->getOptions()->get('nullable'));
316+
}
254317
}

0 commit comments

Comments
 (0)