From 819e35f4fd79581c8798f69f907a8670775aaf6d Mon Sep 17 00:00:00 2001 From: ndifon Date: Sun, 11 Feb 2024 02:17:32 +0100 Subject: [PATCH] Sync Migration Files & Support uniqueIds (#8) * sync migration stubs * - Refactor model to generate unique nanoids for multiple columns - Support nanoids in models with auto-increment models * document uniqueIds changes --- .gitignore | 1 + readme.md | 10 +++- .../Commands/stubs/migration.create.stub | 10 +--- src/Console/Commands/stubs/migration.stub | 10 +--- .../Commands/stubs/migration.update.stub | 10 +--- src/HasNanoids.php | 28 +++++++++- tests/HasNanoidsTest.php | 56 +++++++++++++++++++ tests/TestCase.php | 10 ++++ 8 files changed, 110 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 27a4a66..06499d6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /.vscode .DS_Store .phpunit.result.cache +.phpunit.cache .php_cs.cache _lighthouse_ide_helper.php composer.lock diff --git a/readme.md b/readme.md index be1b09e..d19794f 100644 --- a/readme.md +++ b/readme.md @@ -51,6 +51,8 @@ To create a new migration, use the artisan command `make:nanoid-migration`. All ```php string('id')->primary(); @@ -22,10 +20,8 @@ class {{ class }} extends Migration /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('{{ table }}'); } diff --git a/src/Console/Commands/stubs/migration.stub b/src/Console/Commands/stubs/migration.stub index fd0e437..b02ed8d 100755 --- a/src/Console/Commands/stubs/migration.stub +++ b/src/Console/Commands/stubs/migration.stub @@ -4,24 +4,20 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class {{ class }} extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { // } /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { // } diff --git a/src/Console/Commands/stubs/migration.update.stub b/src/Console/Commands/stubs/migration.update.stub index f1a04eb..4a569ec 100755 --- a/src/Console/Commands/stubs/migration.update.stub +++ b/src/Console/Commands/stubs/migration.update.stub @@ -4,14 +4,12 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class {{ class }} extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { Schema::table('{{ table }}', function (Blueprint $table) { // @@ -20,10 +18,8 @@ class {{ class }} extends Migration /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::table('{{ table }}', function (Blueprint $table) { // diff --git a/src/HasNanoids.php b/src/HasNanoids.php index e720a2f..f7d5510 100644 --- a/src/HasNanoids.php +++ b/src/HasNanoids.php @@ -9,10 +9,24 @@ trait HasNanoids protected static function bootHasNanoids(): void { static::creating(function (self $model) { - $model->{$model->getKeyName()} = $model->generateNanoid(); + foreach ($model->uniqueIds() as $column) { + if (! $model->getAttribute($column)) { + $model->setAttribute($column, $model->generateNanoid()); + } + } }); } + /** + * Get the columns that should receive a unique identifier. + * + * @return array + */ + public function uniqueIds() + { + return [$this->getKeyName()]; + } + /** * Generate a nanoid. */ @@ -87,7 +101,11 @@ protected function getNanoIdAlphabet(): ?string */ public function getKeyType() { - return 'string'; + if (in_array($this->getKeyName(), $this->uniqueIds())) { + return 'string'; + } + + return $this->keyType; } /** @@ -97,6 +115,10 @@ public function getKeyType() */ public function getIncrementing() { - return false; + if (in_array($this->getKeyName(), $this->uniqueIds())) { + return false; + } + + return $this->incrementing; } } diff --git a/tests/HasNanoidsTest.php b/tests/HasNanoidsTest.php index b519cab..9e01e12 100644 --- a/tests/HasNanoidsTest.php +++ b/tests/HasNanoidsTest.php @@ -69,6 +69,34 @@ expect(Str::length($model->getKey()))->toBe(3); }); +it('creates nanoid with multiple ids before saving', function () { + $model = BasicModelWithMultipleIds::create(); + + expect($model->getKey())->toBeString(); + expect($model->another_id)->toBeString(); +}); + +it('creates multiple nanoids that are unique', function () { + $model = BasicModelWithMultipleIds::create(); + + expect($model->getKey())->toBeString(); + expect($model->another_id)->toBeString(); + + expect($model->getKey())->not->toBe($model->another_id); +}); + +it("doesn't override existing id", function () { + $model = BasicModelWithFillable::create(['another_id' => '123']); + + expect($model->another_id)->toBe('123'); +}); + +it('creates nanoid for columns in models with auto-incrementing id', function () { + $model = BasicModelWithDifferentNanoIdColumn::create(); + + expect($model->nano_id)->toBeString(); +}); + abstract class ModelTest extends Model { use HasNanoids; @@ -76,6 +104,16 @@ abstract class ModelTest extends Model protected $table = 'test_migrations_with_string_id'; } +class BasicModelWithDifferentNanoIdColumn extends ModelTest +{ + protected $table = 'test_migration_with_integer_id'; + + public function uniqueIds(): array + { + return ['nano_id']; + } +} + class BasicModel extends ModelTest { } @@ -136,3 +174,21 @@ class BasicModelWithAlphabetAndLength extends ModelTest protected $nanoidLength = 3; } + +class BasicModelWithMultipleIds extends ModelTest +{ + public function uniqueIds(): array + { + return ['id', 'another_id']; + } +} + +class BasicModelWithFillable extends ModelTest +{ + protected $fillable = ['another_id']; + + public function uniqueIds(): array + { + return ['id', 'another_id']; + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index 7e62d22..519064a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -25,6 +25,16 @@ protected function setUpDatabase(): void ->getSchemaBuilder() ->create('test_migrations_with_string_id', function (Blueprint $table): void { $table->string('id')->primary(); + $table->string('another_id')->nullable(); + $table->timestamps(); + }); + + $this->app['db'] + ->connection('testing') + ->getSchemaBuilder() + ->create('test_migration_with_integer_id', function (Blueprint $table): void { + $table->id(); + $table->string('nano_id')->nullable(); $table->timestamps(); }); }