From 9aecd136539d0abb5bf61b989141de97fc13eaa8 Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Fri, 22 Jan 2021 12:10:11 -0500 Subject: [PATCH 1/2] Do not generate foreign key for simple UUID column --- src/Generators/MigrationGenerator.php | 2 +- .../Generators/MigrationGeneratorTest.php | 30 +++++++++++++++++ .../drafts/uuid-without-relationship.yaml | 3 ++ .../migrations/uuid-without-relationship.php | 32 +++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/drafts/uuid-without-relationship.yaml create mode 100644 tests/fixtures/migrations/uuid-without-relationship.php diff --git a/src/Generators/MigrationGenerator.php b/src/Generators/MigrationGenerator.php index ca2f6a97..b37a4e62 100644 --- a/src/Generators/MigrationGenerator.php +++ b/src/Generators/MigrationGenerator.php @@ -400,6 +400,6 @@ private function shouldAddForeignKeyConstraint(\Blueprint\Models\Column $column) return true; } - return in_array($column->dataType(), ['id', 'uuid']) && config('blueprint.use_constraints'); + return in_array($column->dataType(), ['id']) && config('blueprint.use_constraints'); } } diff --git a/tests/Feature/Generators/MigrationGeneratorTest.php b/tests/Feature/Generators/MigrationGeneratorTest.php index 4d5af5de..87df0507 100644 --- a/tests/Feature/Generators/MigrationGeneratorTest.php +++ b/tests/Feature/Generators/MigrationGeneratorTest.php @@ -780,6 +780,35 @@ public function output_works_with_polymorphic_relationships_laravel6() $this->assertEquals(['created' => [$post_migration, $user_migration, $image_migration]], $this->subject->output($tree)); } + /** + * @test + */ + public function output_does_not_generate_relationship_for_uuid() + { + $this->app->config->set('blueprint.use_constraints', true); + + $this->files->expects('stub') + ->with('migration.stub') + ->andReturn($this->stub('migration.stub')); + + $now = Carbon::now(); + Carbon::setTestNow($now); + + $timestamp_path = 'database/migrations/' . $now->format('Y_m_d_His') . '_create_vats_table.php'; + + $this->files->expects('exists') + ->with($timestamp_path) + ->andReturn(false); + + $this->files->expects('put') + ->with($timestamp_path, $this->fixture('migrations/uuid-without-relationship.php')); + + $tokens = $this->blueprint->parse($this->fixture('drafts/uuid-without-relationship.yaml')); + $tree = $this->blueprint->analyze($tokens); + + $this->assertEquals(['created' => [$timestamp_path]], $this->subject->output($tree)); + } + public function modelTreeDataProvider() { return [ @@ -797,6 +826,7 @@ public function modelTreeDataProvider() ['drafts/disable-auto-columns.yaml', 'database/migrations/timestamp_create_states_table.php', 'migrations/disable-auto-columns.php'], ['drafts/uuid-shorthand.yaml', 'database/migrations/timestamp_create_people_table.php', 'migrations/uuid-shorthand.php'], ['drafts/uuid-shorthand-invalid-relationship.yaml', 'database/migrations/timestamp_create_age_cohorts_table.php', 'migrations/uuid-shorthand-invalid-relationship.php'], + ['drafts/uuid-without-relationship.yaml', 'database/migrations/timestamp_create_vats_table.php', 'migrations/uuid-without-relationship.php'], ['drafts/unconventional-foreign-key.yaml', 'database/migrations/timestamp_create_states_table.php', 'migrations/unconventional-foreign-key.php'], ['drafts/resource-statements.yaml', 'database/migrations/timestamp_create_users_table.php', 'migrations/resource-statements.php'], ['drafts/enum-options.yaml', 'database/migrations/timestamp_create_messages_table.php', 'migrations/enum-options.php'], diff --git a/tests/fixtures/drafts/uuid-without-relationship.yaml b/tests/fixtures/drafts/uuid-without-relationship.yaml new file mode 100644 index 00000000..b341595a --- /dev/null +++ b/tests/fixtures/drafts/uuid-without-relationship.yaml @@ -0,0 +1,3 @@ +models: + Vat: + uuid: uuid diff --git a/tests/fixtures/migrations/uuid-without-relationship.php b/tests/fixtures/migrations/uuid-without-relationship.php new file mode 100644 index 00000000..521fdef9 --- /dev/null +++ b/tests/fixtures/migrations/uuid-without-relationship.php @@ -0,0 +1,32 @@ +id(); + $table->uuid('uuid'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('vats'); + } +} From 7c28d2c8d114d170c9dbf8f5380cf48e25c97afb Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Fri, 22 Jan 2021 15:45:06 -0500 Subject: [PATCH 2/2] Support uuid model reference shorthand --- src/Generators/MigrationGenerator.php | 3 +- src/Lexers/ModelLexer.php | 5 ++- tests/Feature/BlueprintTest.php | 1 + .../Generators/MigrationGeneratorTest.php | 29 +++++++++++++++ .../fixtures/drafts/model-relationships.yaml | 1 + tests/fixtures/drafts/uuid-shorthand.yaml | 1 + .../migrations/uuid-shorthand-constraint.php | 37 +++++++++++++++++++ tests/fixtures/migrations/uuid-shorthand.php | 1 + .../models/model-relationships-laravel8.php | 6 +++ 9 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/migrations/uuid-shorthand-constraint.php diff --git a/src/Generators/MigrationGenerator.php b/src/Generators/MigrationGenerator.php index b37a4e62..a9f55ad6 100644 --- a/src/Generators/MigrationGenerator.php +++ b/src/Generators/MigrationGenerator.php @@ -400,6 +400,7 @@ private function shouldAddForeignKeyConstraint(\Blueprint\Models\Column $column) return true; } - return in_array($column->dataType(), ['id']) && config('blueprint.use_constraints'); + return config('blueprint.use_constraints') + && ($column->dataType() === 'id' || $column->dataType() === 'uuid' && Str::endsWith($column->name(), '_id')); } } diff --git a/src/Lexers/ModelLexer.php b/src/Lexers/ModelLexer.php index 59a9290b..e7378adf 100644 --- a/src/Lexers/ModelLexer.php +++ b/src/Lexers/ModelLexer.php @@ -187,7 +187,10 @@ private function buildModel(string $name, array $columns) return collect($modifier)->containsStrict('foreign') || collect($modifier)->has('foreign'); })->flatten()->first(); - if (($column->name() !== 'id') && ($column->dataType() === 'id') || $foreign) { + if (($column->name() !== 'id' && $column->dataType() === 'id') + || ($column->dataType() === 'uuid' && Str::endsWith($column->name(), '_id')) + || $foreign + ) { $reference = $column->name(); if ($foreign && $foreign !== 'foreign') { diff --git a/tests/Feature/BlueprintTest.php b/tests/Feature/BlueprintTest.php index 74fa2b3d..35682bf4 100644 --- a/tests/Feature/BlueprintTest.php +++ b/tests/Feature/BlueprintTest.php @@ -130,6 +130,7 @@ public function it_parses_uuid_shorthand() 'Person' => [ 'id' => 'uuid primary', 'timestamps' => 'timestamps', + 'company_id' => 'uuid', ], ], ], $this->subject->parse($blueprint)); diff --git a/tests/Feature/Generators/MigrationGeneratorTest.php b/tests/Feature/Generators/MigrationGeneratorTest.php index 87df0507..f9153414 100644 --- a/tests/Feature/Generators/MigrationGeneratorTest.php +++ b/tests/Feature/Generators/MigrationGeneratorTest.php @@ -809,6 +809,35 @@ public function output_does_not_generate_relationship_for_uuid() $this->assertEquals(['created' => [$timestamp_path]], $this->subject->output($tree)); } + /** + * @test + */ + public function output_generates_constraint_for_uuid() + { + $this->app->config->set('blueprint.use_constraints', true); + + $this->files->expects('stub') + ->with('migration.stub') + ->andReturn($this->stub('migration.stub')); + + $now = Carbon::now(); + Carbon::setTestNow($now); + + $timestamp_path = 'database/migrations/' . $now->format('Y_m_d_His') . '_create_people_table.php'; + + $this->files->expects('exists') + ->with($timestamp_path) + ->andReturn(false); + + $this->files->expects('put') + ->with($timestamp_path, $this->fixture('migrations/uuid-shorthand-constraint.php')); + + $tokens = $this->blueprint->parse($this->fixture('drafts/uuid-shorthand.yaml')); + $tree = $this->blueprint->analyze($tokens); + + $this->assertEquals(['created' => [$timestamp_path]], $this->subject->output($tree)); + } + public function modelTreeDataProvider() { return [ diff --git a/tests/fixtures/drafts/model-relationships.yaml b/tests/fixtures/drafts/model-relationships.yaml index d2ea5c71..bb225a9e 100644 --- a/tests/fixtures/drafts/model-relationships.yaml +++ b/tests/fixtures/drafts/model-relationships.yaml @@ -1,6 +1,7 @@ models: Subscription: user_id: id + product_id: uuid relationships: belongsToMany: Team hasMany: Order diff --git a/tests/fixtures/drafts/uuid-shorthand.yaml b/tests/fixtures/drafts/uuid-shorthand.yaml index ddd12b14..17e28224 100644 --- a/tests/fixtures/drafts/uuid-shorthand.yaml +++ b/tests/fixtures/drafts/uuid-shorthand.yaml @@ -1,4 +1,5 @@ models: Person: uuid + company_id: uuid timestamps diff --git a/tests/fixtures/migrations/uuid-shorthand-constraint.php b/tests/fixtures/migrations/uuid-shorthand-constraint.php new file mode 100644 index 00000000..7cd790db --- /dev/null +++ b/tests/fixtures/migrations/uuid-shorthand-constraint.php @@ -0,0 +1,37 @@ +uuid('id')->primary(); + $table->uuid('company_id'); + $table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade'); + $table->timestamps(); + }); + + Schema::enableForeignKeyConstraints(); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('people'); + } +} diff --git a/tests/fixtures/migrations/uuid-shorthand.php b/tests/fixtures/migrations/uuid-shorthand.php index ecc5e0c0..0ee39433 100644 --- a/tests/fixtures/migrations/uuid-shorthand.php +++ b/tests/fixtures/migrations/uuid-shorthand.php @@ -15,6 +15,7 @@ public function up() { Schema::create('people', function (Blueprint $table) { $table->uuid('id')->primary(); + $table->uuid('company_id'); $table->timestamps(); }); } diff --git a/tests/fixtures/models/model-relationships-laravel8.php b/tests/fixtures/models/model-relationships-laravel8.php index f75d93dd..be90a572 100644 --- a/tests/fixtures/models/model-relationships-laravel8.php +++ b/tests/fixtures/models/model-relationships-laravel8.php @@ -16,6 +16,7 @@ class Subscription extends Model */ protected $fillable = [ 'user_id', + 'product_id', ]; /** @@ -53,4 +54,9 @@ public function user() { return $this->belongsTo(\App\User::class); } + + public function product() + { + return $this->belongsTo(\App\Product::class); + } }