Skip to content

Commit 554c20f

Browse files
authored
Add Macros for Polymorphic Relationships (#7)
* feat: add morphs snowflake column macros to Blueprint * feat: add tests morphs snowflake polymorphic relationships * Rename blueprints to be more consistent with the framework * Fixing morph index order * Use higher order expectations * Removing integration test with framework * Simplify comment
1 parent 59ac025 commit 554c20f

File tree

6 files changed

+93
-0
lines changed

6 files changed

+93
-0
lines changed

src/Macros/BlueprintMacros.php

+12
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,17 @@ public static function boot(): void
2424
/** @var class-string<Model> $model */
2525
return $this->foreignSnowflake($column ?? (new $model())->getForeignKey());
2626
});
27+
28+
Blueprint::macro('snowflakeMorphs', function (string $name, ?string $indexName = null): void {
29+
$this->snowflake("{$name}_id");
30+
$this->text("{$name}_type");
31+
$this->index(["{$name}_type", "{$name}_id"], $indexName);
32+
});
33+
34+
Blueprint::macro('nullableSnowflakeMorphs', function (string $name, ?string $indexName = null): void {
35+
$this->snowflake("{$name}_id")->nullable();
36+
$this->text("{$name}_type")->nullable();
37+
$this->index(["{$name}_type", "{$name}_id"], $indexName);
38+
});
2739
}
2840
}

tests/Feature/Mixins/BlueprintMixinTest.php

+20
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,23 @@
4646
'alter table "snowflake" add column "user_id" integer not null',
4747
]);
4848
});
49+
50+
it('adds morph snowflake columns', function () {
51+
test()->blueprint->snowflakeMorphs('taggable');
52+
53+
expect((test()->sql)())->toBe([
54+
'alter table "snowflake" add column "taggable_id" integer not null',
55+
'alter table "snowflake" add column "taggable_type" text not null',
56+
'create index "snowflake_taggable_type_taggable_id_index" on "snowflake" ("taggable_type", "taggable_id")',
57+
]);
58+
});
59+
60+
it('adds nullable morph snowflake columns', function () {
61+
test()->blueprint->nullableSnowflakeMorphs('taggable');
62+
63+
expect((test()->sql)())->toBe([
64+
'alter table "snowflake" add column "taggable_id" integer',
65+
'alter table "snowflake" add column "taggable_type" text',
66+
'create index "snowflake_taggable_type_taggable_id_index" on "snowflake" ("taggable_type", "taggable_id")',
67+
]);
68+
});

workbench/app/Models/Post.php

+7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use CalebDW\Laraflake\Concerns\HasSnowflakes;
99
use Illuminate\Database\Eloquent\Model;
1010
use Illuminate\Database\Eloquent\Relations\BelongsTo;
11+
use Illuminate\Database\Eloquent\Relations\MorphMany;
1112

1213
class Post extends Model
1314
{
@@ -35,4 +36,10 @@ public function getRouteKeyName(): string
3536
{
3637
return 'slug';
3738
}
39+
40+
/** @return MorphMany<Tag, $this> */
41+
public function tags(): MorphMany
42+
{
43+
return $this->morphMany(Tag::class, 'taggable');
44+
}
3845
}

workbench/app/Models/Tag.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Workbench\App\Models;
6+
7+
use CalebDW\Laraflake\Concerns\HasSnowflakes;
8+
use Illuminate\Database\Eloquent\Model;
9+
use Illuminate\Database\Eloquent\Relations\MorphTo;
10+
11+
class Tag extends Model
12+
{
13+
use HasSnowflakes;
14+
15+
protected $guarded = [];
16+
17+
/** @return MorphTo<Model, $this> */
18+
public function taggable(): MorphTo
19+
{
20+
return $this->morphTo();
21+
}
22+
}

workbench/app/Models/User.php

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use CalebDW\Laraflake\Concerns\HasSnowflakes;
88
use Illuminate\Database\Eloquent\Model;
99
use Illuminate\Database\Eloquent\Relations\HasMany;
10+
use Illuminate\Database\Eloquent\Relations\MorphMany;
1011

1112
class User extends Model
1213
{
@@ -19,4 +20,10 @@ public function posts(): HasMany
1920
{
2021
return $this->hasMany(Post::class);
2122
}
23+
24+
/** @return MorphMany<Tag, $this> */
25+
public function tags(): MorphMany
26+
{
27+
return $this->morphMany(Tag::class, 'taggable');
28+
}
2229
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Illuminate\Database\Migrations\Migration;
6+
use Illuminate\Database\Schema\Blueprint;
7+
use Illuminate\Support\Facades\Schema;
8+
9+
return new class extends Migration
10+
{
11+
public function up(): void
12+
{
13+
Schema::create('tags', function (Blueprint $table) {
14+
$table->snowflake()->primary();
15+
$table->string('name');
16+
$table->snowflakeMorphs('taggable');
17+
$table->timestamps();
18+
});
19+
}
20+
21+
public function down(): void
22+
{
23+
Schema::dropIfExists('tags');
24+
}
25+
};

0 commit comments

Comments
 (0)