Skip to content

Commit 8704357

Browse files
Infer foreign table reference from id attribute (#191)
1 parent 5282450 commit 8704357

File tree

5 files changed

+131
-3
lines changed

5 files changed

+131
-3
lines changed

src/Generators/MigrationGenerator.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ protected function buildDefinition(Model $model)
131131
$foreign_modifier = $column->isForeignKey();
132132

133133
if ($this->shouldAddForeignKeyConstraint($column)) {
134-
$foreign = $this->buildForeignKey($column->name(), $foreign_modifier === 'foreign' ? null : $foreign_modifier, $column->dataType());
134+
$foreign = $this->buildForeignKey($column->name(), $foreign_modifier === 'foreign' ? null : $foreign_modifier, $column->dataType(), $column->attributes());
135135
if ($column->dataType() === 'id' && $this->isLaravel7orNewer()) {
136136
$column_definition = $foreign;
137137
$foreign = '';
@@ -198,7 +198,7 @@ protected function buildPivotTableDefinition(array $segments)
198198
return trim($definition);
199199
}
200200

201-
protected function buildForeignKey(string $column_name, ?string $on, string $type)
201+
protected function buildForeignKey(string $column_name, ?string $on, string $type, array $attributes = [])
202202
{
203203
if (is_null($on)) {
204204
$table = Str::plural(Str::beforeLast($column_name, '_'));
@@ -211,6 +211,10 @@ protected function buildForeignKey(string $column_name, ?string $on, string $typ
211211
$column = Str::afterLast($column_name, '_');
212212
}
213213

214+
if ($type === 'id' && !empty($attributes)) {
215+
$table = Str::lower(Str::plural($attributes[0]));
216+
}
217+
214218
if ($this->isLaravel7orNewer() && $type === 'id') {
215219
if ($column_name === Str::singular($table) . '_' . $column) {
216220
return self::INDENT . '$table->foreignId' . "('{$column_name}')->constrained()->cascadeOnDelete()";

tests/Feature/Generator/MigrationGeneratorTest.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,62 @@ public function output_uses_proper_data_type_for_id_columns_in_laravel6()
125125
$this->assertEquals(['created' => [$timestamp_path]], $this->subject->output($tree));
126126
}
127127

128+
/**
129+
* @test
130+
*/
131+
public function output_creates_constraints_for_unconventional_foreign_reference_migration()
132+
{
133+
$this->app->config->set('blueprint.use_constraints', true);
134+
135+
$this->files->expects('stub')
136+
->with('migration.stub')
137+
->andReturn(file_get_contents('stubs/migration.stub'));
138+
139+
$now = Carbon::now();
140+
Carbon::setTestNow($now);
141+
142+
$model_migration = str_replace('timestamp', $now->format('Y_m_d_His'), 'database/migrations/timestamp_create_comments_table.php');
143+
144+
$this->files->expects('put')
145+
->with($model_migration, $this->fixture('migrations/relationships-constraints.php'));
146+
147+
$tokens = $this->blueprint->parse($this->fixture('definitions/relationships.bp'));
148+
$tree = $this->blueprint->analyze($tokens);
149+
150+
$this->assertEquals(['created' => [$model_migration]], $this->subject->output($tree));
151+
}
152+
153+
/**
154+
* @test
155+
*/
156+
public function output_creates_constraints_for_unconventional_foreign_reference_migration_laravel6()
157+
{
158+
$this->app->config->set('blueprint.use_constraints', true);
159+
160+
$app = \Mockery::mock();
161+
$app->shouldReceive('version')
162+
->withNoArgs()
163+
->andReturn('6.0.0');
164+
App::swap($app);
165+
166+
$this->files->expects('stub')
167+
->with('migration.stub')
168+
->andReturn(file_get_contents('stubs/migration.stub'));
169+
170+
$now = Carbon::now();
171+
Carbon::setTestNow($now);
172+
173+
$model_migration = str_replace('timestamp', $now->format('Y_m_d_His'), 'database/migrations/timestamp_create_comments_table.php');
174+
175+
$this->files->expects('put')
176+
->with($model_migration, $this->fixture('migrations/relationships-constraints-laravel6.php'));
177+
178+
$tokens = $this->blueprint->parse($this->fixture('definitions/relationships.bp'));
179+
$tree = $this->blueprint->analyze($tokens);
180+
181+
$this->assertEquals(['created' => [$model_migration]], $this->subject->output($tree));
182+
}
183+
128184
/**
129185
* @test
130186
*/
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
models:
22
Comment:
33
post_id: id
4-
author_id: id:user
4+
author_id: id:user
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class CreateCommentsTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::create('comments', function (Blueprint $table) {
17+
$table->bigIncrements('id');
18+
$table->unsignedBigInteger('post_id');
19+
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
20+
$table->unsignedBigInteger('author_id');
21+
$table->foreign('author_id')->references('id')->on('users')->onDelete('cascade');
22+
$table->timestamps();
23+
});
24+
}
25+
26+
/**
27+
* Reverse the migrations.
28+
*
29+
* @return void
30+
*/
31+
public function down()
32+
{
33+
Schema::dropIfExists('comments');
34+
}
35+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class CreateCommentsTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::create('comments', function (Blueprint $table) {
17+
$table->id();
18+
$table->foreignId('post_id')->constrained()->cascadeOnDelete();
19+
$table->foreignId('author_id')->constrained('users')->cascadeOnDelete();
20+
$table->timestamps();
21+
});
22+
}
23+
24+
/**
25+
* Reverse the migrations.
26+
*
27+
* @return void
28+
*/
29+
public function down()
30+
{
31+
Schema::dropIfExists('comments');
32+
}
33+
}

0 commit comments

Comments
 (0)