Skip to content

Commit 0184045

Browse files
authored
Merge pull request #15 from recca0120/feat/multiple-keys
support awobaz/compoships
2 parents dbcfd94 + d32e7e7 commit 0184045

File tree

10 files changed

+163
-67
lines changed

10 files changed

+163
-67
lines changed

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"php-http/client-common": "^2.7"
2929
},
3030
"require-dev": {
31+
"awobaz/compoships": "^2.3",
3132
"doctrine/dbal": "^3.5",
3233
"guzzlehttp/guzzle": "^7.5",
3334
"mockery/mockery": "^1.5",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration {
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
Schema::table('users', function (Blueprint $table) {
16+
$table->foreignId('category_id');
17+
});
18+
19+
Schema::create('tasks', function (Blueprint $table) {
20+
$table->id();
21+
$table->foreignId('team_id');
22+
$table->foreignId('category_id');
23+
$table->timestamps();
24+
});
25+
}
26+
27+
/**
28+
* Reverse the migrations.
29+
*
30+
* @return void
31+
*/
32+
public function down()
33+
{
34+
Schema::dropIfExists('tasks');
35+
Schema::table('users', function (Blueprint $table) {
36+
$table->dropColumn(['category_id']);
37+
});
38+
}
39+
};

src/Relation.php

+30-17
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111

1212
class Relation
1313
{
14+
private static array $relationMap = [
15+
\Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo::class => BelongsTo::class,
16+
\Awobaz\Compoships\Database\Eloquent\Relations\HasOne::class => HasOne::class,
17+
\Awobaz\Compoships\Database\Eloquent\Relations\HasMany::class => HasMany::class,
18+
];
1419
private array $attributes;
1520

1621
public function __construct(array $attributes)
@@ -20,7 +25,7 @@ public function __construct(array $attributes)
2025

2126
public function type(): string
2227
{
23-
return $this->attributes['type'];
28+
return self::$relationMap[$this->attributes['type']] ?? $this->attributes['type'];
2429
}
2530

2631
public function related(): string
@@ -33,34 +38,38 @@ public function parent(): string
3338
return $this->attributes['parent'];
3439
}
3540

36-
public function localKey(): string
41+
public function localKeys(): array
3742
{
38-
return $this->attributes['local_key'];
43+
return (array) $this->attributes['local_key'];
3944
}
4045

4146
public function localTable(): string
4247
{
43-
return Helpers::getTableName($this->localKey());
48+
return Helpers::getTableName($this->localKeys()[0]);
4449
}
4550

46-
public function localColumn(): string
51+
public function localColumns(): array
4752
{
48-
return Helpers::getColumnName($this->localKey());
53+
return array_map(static function (string $column) {
54+
return Helpers::getColumnName($column);
55+
}, $this->localKeys());
4956
}
5057

51-
public function foreignKey(): string
58+
public function foreignKeys(): array
5259
{
53-
return $this->attributes['foreign_key'];
60+
return (array) $this->attributes['foreign_key'];
5461
}
5562

5663
public function foreignTable(): string
5764
{
58-
return Helpers::getTableName($this->foreignKey());
65+
return Helpers::getTableName($this->foreignKeys()[0]);
5966
}
6067

61-
public function foreignColumn(): string
68+
public function foreignColumns(): array
6269
{
63-
return Helpers::getColumnName($this->foreignKey());
70+
return array_map(static function (string $column) {
71+
return Helpers::getColumnName($column);
72+
}, $this->foreignKeys());
6473
}
6574

6675
public function morphClass(): ?string
@@ -119,8 +128,8 @@ public function relatedRelation(): Relation
119128
'type' => $reverseLookup[$type] ?? $type,
120129
'related' => $this->parent(),
121130
'parent' => $this->related(),
122-
'local_key' => $this->foreignKey(),
123-
'foreign_key' => $this->localKey(),
131+
'local_key' => $this->foreignKeys(),
132+
'foreign_key' => $this->localKeys(),
124133
'pivot' => $this->attributes['pivot'] ?? null,
125134
'morph_class' => $this->morphClass(),
126135
'morph_type' => $this->morphType(),
@@ -149,15 +158,19 @@ public function sortByRelation(): int
149158
*/
150159
public function sortByKeys(): array
151160
{
152-
return [$this->type(), $this->localKey(), $this->foreignKey()];
161+
return [$this->type(), $this->localKeys(), $this->foreignKeys()];
153162
}
154163

155164
public function uniqueId(): string
156165
{
157-
$localKey = Helpers::getTableName($this->localKey());
158-
$foreignKey = Helpers::getTableName($this->foreignKey());
166+
$sortBy = [];
167+
foreach ($this->localKeys() as $localKey) {
168+
$sortBy[] = Helpers::getTableName($localKey);
169+
}
170+
foreach ($this->foreignKeys() as $foreignKey) {
171+
$sortBy[] = Helpers::getTableName($foreignKey);
172+
}
159173

160-
$sortBy = [$localKey, $foreignKey];
161174
sort($sortBy);
162175

163176
return implode('::', $sortBy);

src/Template/DDL.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ private function renderRelation(Relation $relation): string
7979
return sprintf(
8080
'ALTER TABLE %s ADD FOREIGN KEY (%s) REFERENCES %s (%s)',
8181
$relation->localTable(),
82-
$relation->localColumn(),
82+
implode(', ', $relation->localColumns()),
8383
$relation->foreignTable(),
84-
$relation->foreignColumn()
84+
implode(', ', $relation->foreignColumns())
8585
);
8686
}
8787
}

src/Template/Er.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ private function renderTable(Table $table): string
7777
$primaryKeys = $table->getPrimaryKeys();
7878
$indexes = $table
7979
->getRelations()
80-
->flatMap(fn (Relation $relation) => [$relation->localColumn(), $relation->morphColumn()])
81-
->filter();
80+
->flatMap(fn (Relation $relation) => [...$relation->localColumns(), $relation->morphColumn()])
81+
->filter()
82+
->unique();
8283

8384
return $table->getColumns()
8485
->map(fn (ColumnSchema $column) => $this->renderColumn($column, $primaryKeys, $indexes))

tests/Fixtures/Models/Task.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;
4+
5+
use Awobaz\Compoships\Compoships;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
class Task extends Model
9+
{
10+
use Compoships;
11+
12+
public function user()
13+
{
14+
return $this->belongsTo(User::class, ['team_id', 'category_id'], ['team_id', 'category_id']);
15+
}
16+
}

tests/Fixtures/Models/User.php

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;
44

5+
use Awobaz\Compoships\Compoships;
56
use Illuminate\Database\Eloquent\Model;
67
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
78
use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -13,6 +14,7 @@
1314
class User extends Model
1415
{
1516
use HasRoles;
17+
use Compoships;
1618

1719
protected $fillable = ['name', 'email', 'password'];
1820

@@ -59,4 +61,9 @@ public function devices(): BelongsToMany
5961
{
6062
return $this->belongsToMany(Device::class, 'user_device');
6163
}
64+
65+
public function tasks()
66+
{
67+
return $this->hasMany(Task::class, ['team_id', 'category_id'], ['team_id', 'category_id']);
68+
}
6269
}

0 commit comments

Comments
 (0)