From 2d825493bda3227e6ebec34358bc856ca6336b79 Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Wed, 13 Mar 2024 15:41:32 -0400 Subject: [PATCH] Re-apply fixes from #661 (#681) --- src/Generators/MigrationGenerator.php | 4 +- src/Generators/ModelGenerator.php | 10 +++ src/Models/Model.php | 9 +++ .../Generators/MigrationGeneratorTest.php | 64 +++++++++++++++++++ .../drafts/belongs-to-many-using-uuids.yaml | 10 +++ tests/fixtures/drafts/belongs-to-many.yaml | 2 +- ...traints-using-ulid-columns-diary-model.php | 31 +++++++++ ...aints-using-ulid-columns-journey-model.php | 33 ++++++++++ ...traints-using-uuid-columns-diary-model.php | 31 +++++++++ ...aints-using-uuid-columns-journey-model.php | 28 ++++++++ ...vot-key-constraints-using-ulid-columns.php | 31 +++++++++ ...vot-key-constraints-using-uuid-columns.php | 31 +++++++++ 12 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/drafts/belongs-to-many-using-uuids.yaml create mode 100644 tests/fixtures/migrations/belongs-to-many-key-constraints-using-ulid-columns-diary-model.php create mode 100644 tests/fixtures/migrations/belongs-to-many-key-constraints-using-ulid-columns-journey-model.php create mode 100644 tests/fixtures/migrations/belongs-to-many-key-constraints-using-uuid-columns-diary-model.php create mode 100644 tests/fixtures/migrations/belongs-to-many-key-constraints-using-uuid-columns-journey-model.php create mode 100644 tests/fixtures/migrations/belongs-to-many-pivot-key-constraints-using-ulid-columns.php create mode 100644 tests/fixtures/migrations/belongs-to-many-pivot-key-constraints-using-uuid-columns.php diff --git a/src/Generators/MigrationGenerator.php b/src/Generators/MigrationGenerator.php index 895fdf12..b8c63a5c 100644 --- a/src/Generators/MigrationGenerator.php +++ b/src/Generators/MigrationGenerator.php @@ -390,7 +390,9 @@ protected function buildPivotTableDefinition(array $segments, array $models = [] if (config('blueprint.use_constraints')) { $this->hasForeignKeyConstraints = true; - $definition .= $this->buildForeignKey($foreign, $on, 'id') . ';' . PHP_EOL; + + $type = isset($models[$segment]) ? $models[$segment]->idType() : 'id'; + $definition .= $this->buildForeignKey($foreign, $on, $type) . ';' . PHP_EOL; } else { $definition .= $this->generateForeignKeyDefinition($segment, $foreign, $models); } diff --git a/src/Generators/ModelGenerator.php b/src/Generators/ModelGenerator.php index 9f1e38e8..6e7f578f 100644 --- a/src/Generators/ModelGenerator.php +++ b/src/Generators/ModelGenerator.php @@ -91,6 +91,16 @@ protected function buildClassPhpDoc(Model $model): string $phpDoc .= PHP_EOL; $phpDoc .= ' * @property string|null $' . $column->name() . '_type'; $phpDoc .= PHP_EOL; + } elseif ($column->dataType() === 'ulidMorphs') { + $phpDoc .= ' * @property string $' . $column->name() . '_id'; + $phpDoc .= PHP_EOL; + $phpDoc .= ' * @property string $' . $column->name() . '_type'; + $phpDoc .= PHP_EOL; + } elseif ($column->dataType() === 'nullableUlidMorphs') { + $phpDoc .= ' * @property string|null $' . $column->name() . '_id'; + $phpDoc .= PHP_EOL; + $phpDoc .= ' * @property string|null $' . $column->name() . '_type'; + $phpDoc .= PHP_EOL; } elseif ($column->dataType() === 'uuidMorphs') { $phpDoc .= ' * @property string $' . $column->name() . '_id'; $phpDoc .= PHP_EOL; diff --git a/src/Models/Model.php b/src/Models/Model.php index 6ffb29e9..207e2458 100644 --- a/src/Models/Model.php +++ b/src/Models/Model.php @@ -111,6 +111,15 @@ public function usesUuids(): bool return $this->usesPrimaryKey() && $this->columns[$this->primaryKey]->dataType() === 'uuid'; } + public function idType(): ?string + { + if (!$this->usesPrimaryKey()) { + return null; + } + + return $this->columns[$this->primaryKey]->dataType(); + } + public function disablePrimaryKey(): void { $this->primaryKey = false; diff --git a/tests/Feature/Generators/MigrationGeneratorTest.php b/tests/Feature/Generators/MigrationGeneratorTest.php index 807036a2..f265cc3a 100644 --- a/tests/Feature/Generators/MigrationGeneratorTest.php +++ b/tests/Feature/Generators/MigrationGeneratorTest.php @@ -245,6 +245,70 @@ public function output_also_updates_pivot_table_migration(): void $this->assertEquals(['updated' => [$model_migration, $pivot_migration]], $this->subject->output($tree, true)); } + #[Test] + public function output_also_creates_constraints_for_pivot_table_migration_for_ulids(): void + { + $this->app->config->set('blueprint.use_constraints', true); + + $this->filesystem->expects('stub') + ->with('migration.stub') + ->andReturn($this->stub('migration.stub')); + + $now = Carbon::now(); + Carbon::setTestNow($now); + + $journey_model_migration = str_replace('timestamp', $now->copy()->subSeconds(2)->format('Y_m_d_His'), 'database/migrations/timestamp_create_journeys_table.php'); + $diary_model_migration = str_replace('timestamp', $now->copy()->subSecond()->format('Y_m_d_His'), 'database/migrations/timestamp_create_diaries_table.php'); + $pivot_migration = str_replace('timestamp', $now->format('Y_m_d_His'), 'database/migrations/timestamp_create_diary_journey_table.php'); + + $this->filesystem->expects('exists')->times(3)->andReturn(false); + + $this->filesystem->expects('put') + ->with($journey_model_migration, $this->fixture('migrations/belongs-to-many-key-constraints-using-ulid-columns-journey-model.php')); + $this->filesystem->expects('put') + ->with($diary_model_migration, $this->fixture('migrations/belongs-to-many-key-constraints-using-ulid-columns-diary-model.php')); + + $this->filesystem->expects('put') + ->with($pivot_migration, $this->fixture('migrations/belongs-to-many-pivot-key-constraints-using-ulid-columns.php')); + + $tokens = $this->blueprint->parse($this->fixture('drafts/belongs-to-many-using-ulids.yaml')); + $tree = $this->blueprint->analyze($tokens); + + $this->assertEquals(['created' => [$journey_model_migration, $diary_model_migration, $pivot_migration]], $this->subject->output($tree)); + } + + #[Test] + public function output_also_creates_constraints_for_pivot_table_migration_for_uuids(): void + { + $this->app->config->set('blueprint.use_constraints', true); + + $this->filesystem->expects('stub') + ->with('migration.stub') + ->andReturn($this->stub('migration.stub')); + + $now = Carbon::now(); + Carbon::setTestNow($now); + + $journey_model_migration = str_replace('timestamp', $now->copy()->subSeconds(2)->format('Y_m_d_His'), 'database/migrations/timestamp_create_journeys_table.php'); + $diary_model_migration = str_replace('timestamp', $now->copy()->subSecond()->format('Y_m_d_His'), 'database/migrations/timestamp_create_diaries_table.php'); + $pivot_migration = str_replace('timestamp', $now->format('Y_m_d_His'), 'database/migrations/timestamp_create_diary_journey_table.php'); + + $this->filesystem->expects('exists')->times(3)->andReturn(false); + + $this->filesystem->expects('put') + ->with($journey_model_migration, $this->fixture('migrations/belongs-to-many-key-constraints-using-uuid-columns-journey-model.php')); + $this->filesystem->expects('put') + ->with($diary_model_migration, $this->fixture('migrations/belongs-to-many-key-constraints-using-uuid-columns-diary-model.php')); + + $this->filesystem->expects('put') + ->with($pivot_migration, $this->fixture('migrations/belongs-to-many-pivot-key-constraints-using-uuid-columns.php')); + + $tokens = $this->blueprint->parse($this->fixture('drafts/belongs-to-many-using-uuids.yaml')); + $tree = $this->blueprint->analyze($tokens); + + $this->assertEquals(['created' => [$journey_model_migration, $diary_model_migration, $pivot_migration]], $this->subject->output($tree)); + } + #[Test] public function output_also_creates_constraints_for_pivot_table_migration(): void { diff --git a/tests/fixtures/drafts/belongs-to-many-using-uuids.yaml b/tests/fixtures/drafts/belongs-to-many-using-uuids.yaml new file mode 100644 index 00000000..f5100b62 --- /dev/null +++ b/tests/fixtures/drafts/belongs-to-many-using-uuids.yaml @@ -0,0 +1,10 @@ +models: + Journey: + uuid + name: string + relationships: + belongsToMany: Diary + Diary: + uuid + relationships: + belongsToMany: Journey diff --git a/tests/fixtures/drafts/belongs-to-many.yaml b/tests/fixtures/drafts/belongs-to-many.yaml index 2ba94499..aa08c35c 100644 --- a/tests/fixtures/drafts/belongs-to-many.yaml +++ b/tests/fixtures/drafts/belongs-to-many.yaml @@ -3,4 +3,4 @@ models: name: string user_id: id relationships: - belongstoMany: Diary + belongsToMany: Diary diff --git a/tests/fixtures/migrations/belongs-to-many-key-constraints-using-ulid-columns-diary-model.php b/tests/fixtures/migrations/belongs-to-many-key-constraints-using-ulid-columns-diary-model.php new file mode 100644 index 00000000..96987a13 --- /dev/null +++ b/tests/fixtures/migrations/belongs-to-many-key-constraints-using-ulid-columns-diary-model.php @@ -0,0 +1,31 @@ +ulid('id')->primary(); + $table->timestamps(); + }); + + Schema::enableForeignKeyConstraints(); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('diaries'); + } +}; diff --git a/tests/fixtures/migrations/belongs-to-many-key-constraints-using-ulid-columns-journey-model.php b/tests/fixtures/migrations/belongs-to-many-key-constraints-using-ulid-columns-journey-model.php new file mode 100644 index 00000000..a97c3967 --- /dev/null +++ b/tests/fixtures/migrations/belongs-to-many-key-constraints-using-ulid-columns-journey-model.php @@ -0,0 +1,33 @@ +ulid('id')->primary(); + $table->string('name'); + $table->foreignUlid('user_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate(); + $table->timestamps(); + }); + + Schema::enableForeignKeyConstraints(); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('journeys'); + } +}; diff --git a/tests/fixtures/migrations/belongs-to-many-key-constraints-using-uuid-columns-diary-model.php b/tests/fixtures/migrations/belongs-to-many-key-constraints-using-uuid-columns-diary-model.php new file mode 100644 index 00000000..fcf0c35e --- /dev/null +++ b/tests/fixtures/migrations/belongs-to-many-key-constraints-using-uuid-columns-diary-model.php @@ -0,0 +1,31 @@ +uuid('id')->primary(); + $table->timestamps(); + }); + + Schema::enableForeignKeyConstraints(); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('diaries'); + } +}; diff --git a/tests/fixtures/migrations/belongs-to-many-key-constraints-using-uuid-columns-journey-model.php b/tests/fixtures/migrations/belongs-to-many-key-constraints-using-uuid-columns-journey-model.php new file mode 100644 index 00000000..e09a9234 --- /dev/null +++ b/tests/fixtures/migrations/belongs-to-many-key-constraints-using-uuid-columns-journey-model.php @@ -0,0 +1,28 @@ +uuid('id')->primary(); + $table->string('name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('journeys'); + } +}; diff --git a/tests/fixtures/migrations/belongs-to-many-pivot-key-constraints-using-ulid-columns.php b/tests/fixtures/migrations/belongs-to-many-pivot-key-constraints-using-ulid-columns.php new file mode 100644 index 00000000..6344cb07 --- /dev/null +++ b/tests/fixtures/migrations/belongs-to-many-pivot-key-constraints-using-ulid-columns.php @@ -0,0 +1,31 @@ +foreignUlid('diary_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate(); + $table->foreignUlid('journey_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate(); + }); + + Schema::enableForeignKeyConstraints(); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('diary_journey'); + } +}; diff --git a/tests/fixtures/migrations/belongs-to-many-pivot-key-constraints-using-uuid-columns.php b/tests/fixtures/migrations/belongs-to-many-pivot-key-constraints-using-uuid-columns.php new file mode 100644 index 00000000..66c63ef1 --- /dev/null +++ b/tests/fixtures/migrations/belongs-to-many-pivot-key-constraints-using-uuid-columns.php @@ -0,0 +1,31 @@ +foreignUuid('diary_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate(); + $table->foreignUuid('journey_id')->constrained()->cascadeOnDelete()->cascadeOnUpdate(); + }); + + Schema::enableForeignKeyConstraints(); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('diary_journey'); + } +};