Skip to content

Commit b789904

Browse files
Generate proper fake relationship for model factory (#223)
1 parent 383f3a7 commit b789904

File tree

5 files changed

+49
-8
lines changed

5 files changed

+49
-8
lines changed

src/Generators/FactoryGenerator.php

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,41 @@ protected function buildDefinition(Model $model)
7272
continue;
7373
}
7474

75-
if (in_array($column->dataType(), ['id', 'uuid'])) {
76-
$foreign = $column->isForeignKey();
75+
$foreign = $column->isForeignKey();
76+
if ($foreign) {
77+
$table = Str::beforeLast($column->name(), '_id');
78+
$key = 'id';
79+
80+
if (Str::contains($foreign, '.')) {
81+
[$table, $key] = explode('.', $foreign);
82+
} elseif ($foreign !== 'foreign') {
83+
$table = $foreign;
84+
85+
if (Str::startsWith($column->name(), $foreign . '_')) {
86+
$key = Str::after($column->name(), $foreign . '_');
87+
} elseif (Str::startsWith($column->name(), Str::snake(Str::singular($foreign)) . '_')) {
88+
$key = Str::after($column->name(), Str::snake(Str::singular($foreign)) . '_');
89+
} elseif (!Str::endsWith($column->name(), '_id')) {
90+
$key = $column->name();
91+
}
92+
}
93+
94+
$class = Str::studly(Str::singular($table));
7795

78-
if ($foreign && $foreign !== 'foreign') {
79-
$class = Str::studly(Str::singular($foreign));
96+
if ($key === 'id') {
97+
$definition .= self::INDENT . "'{$column->name()}' => ";
98+
$definition .= sprintf('factory(%s::class)', '\\' . $model->fullyQualifiedNamespace() . '\\' . $class);
99+
$definition .= ',' . PHP_EOL;
80100
} else {
81-
$name = Str::beforeLast($column->name(), '_id');
82-
$class = Str::studly($column->attributes()[0] ?? $name);
101+
$definition .= self::INDENT . "'{$column->name()}' => function () {";
102+
$definition .= PHP_EOL;
103+
$definition .= self::INDENT . ' ' . sprintf('return factory(%s::class)->create()->%s;', '\\' . $model->fullyQualifiedNamespace() . '\\' . $class, $key);
104+
$definition .= PHP_EOL;
105+
$definition .= self::INDENT . '},' . PHP_EOL;
83106
}
107+
} elseif (in_array($column->dataType(), ['id', 'uuid'])) {
108+
$name = Str::beforeLast($column->name(), '_id');
109+
$class = Str::studly($column->attributes()[0] ?? $name);
84110

85111
$definition .= self::INDENT . "'{$column->name()}' => ";
86112
$definition .= sprintf('factory(%s::class)', '\\' . $model->fullyQualifiedNamespace() . '\\' . $class);

tests/Feature/Generator/FactoryGeneratorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public function modelTreeDataProvider()
149149
['definitions/unconventional.bp', 'database/factories/TeamFactory.php', 'factories/unconventional.php'],
150150
['definitions/model-modifiers.bp', 'database/factories/ModifierFactory.php', 'factories/model-modifiers.php'],
151151
['definitions/model-key-constraints.bp', 'database/factories/OrderFactory.php', 'factories/model-key-constraints.php'],
152-
// ['definitions/unconventional-foreign-key.bp', 'database/factories/StateFactory.php', 'factories/unconventional-foreign-key.php'],
152+
['definitions/unconventional-foreign-key.bp', 'database/factories/StateFactory.php', 'factories/unconventional-foreign-key.php'],
153153
];
154154
}
155155
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
models:
22
State:
33
name: string
4-
country_code: string foreign:countries.code
4+
countries_id: id foreign:countries
5+
country_code: string foreign:countries
6+
ccid: string foreign:countries
7+
c_code: string foreign:countries.code

tests/fixtures/factories/unconventional-foreign-key.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@
88
$factory->define(State::class, function (Faker $faker) {
99
return [
1010
'name' => $faker->name,
11+
'countries_id' => factory(\App\Country::class),
1112
'country_code' => function () {
1213
return factory(\App\Country::class)->create()->code;
1314
},
15+
'ccid' => function () {
16+
return factory(\App\Country::class)->create()->ccid;
17+
},
18+
'c_code' => function () {
19+
return factory(\App\Country::class)->create()->code;
20+
},
1421
];
1522
});

tests/fixtures/migrations/unconventional-foreign-key.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@ public function up()
1616
Schema::create('states', function (Blueprint $table) {
1717
$table->id();
1818
$table->string('name');
19+
$table->foreignId('countries_id')->constrained('countries')->cascadeOnDelete();
1920
$table->string('country_code');
2021
$table->foreign('country_code')->references('code')->on('countries')->onDelete('cascade');
22+
$table->string('ccid');
23+
$table->foreign('ccid')->references('ccid')->on('countries')->onDelete('cascade');
24+
$table->string('c_code');
25+
$table->foreign('c_code')->references('code')->on('countries')->onDelete('cascade');
2126
$table->timestamps();
2227
});
2328
}

0 commit comments

Comments
 (0)