diff --git a/src/Generators/FactoryGenerator.php b/src/Generators/FactoryGenerator.php index 8a12f13f..65e35f5e 100644 --- a/src/Generators/FactoryGenerator.php +++ b/src/Generators/FactoryGenerator.php @@ -72,15 +72,41 @@ protected function buildDefinition(Model $model) continue; } - if (in_array($column->dataType(), ['id', 'uuid'])) { - $foreign = $column->isForeignKey(); + $foreign = $column->isForeignKey(); + if ($foreign) { + $table = Str::beforeLast($column->name(), '_id'); + $key = 'id'; + + if (Str::contains($foreign, '.')) { + [$table, $key] = explode('.', $foreign); + } elseif ($foreign !== 'foreign') { + $table = $foreign; + + if (Str::startsWith($column->name(), $foreign . '_')) { + $key = Str::after($column->name(), $foreign . '_'); + } elseif (Str::startsWith($column->name(), Str::snake(Str::singular($foreign)) . '_')) { + $key = Str::after($column->name(), Str::snake(Str::singular($foreign)) . '_'); + } elseif (!Str::endsWith($column->name(), '_id')) { + $key = $column->name(); + } + } + + $class = Str::studly(Str::singular($table)); - if ($foreign && $foreign !== 'foreign') { - $class = Str::studly(Str::singular($foreign)); + if ($key === 'id') { + $definition .= self::INDENT . "'{$column->name()}' => "; + $definition .= sprintf('factory(%s::class)', '\\' . $model->fullyQualifiedNamespace() . '\\' . $class); + $definition .= ',' . PHP_EOL; } else { - $name = Str::beforeLast($column->name(), '_id'); - $class = Str::studly($column->attributes()[0] ?? $name); + $definition .= self::INDENT . "'{$column->name()}' => function () {"; + $definition .= PHP_EOL; + $definition .= self::INDENT . ' ' . sprintf('return factory(%s::class)->create()->%s;', '\\' . $model->fullyQualifiedNamespace() . '\\' . $class, $key); + $definition .= PHP_EOL; + $definition .= self::INDENT . '},' . PHP_EOL; } + } elseif (in_array($column->dataType(), ['id', 'uuid'])) { + $name = Str::beforeLast($column->name(), '_id'); + $class = Str::studly($column->attributes()[0] ?? $name); $definition .= self::INDENT . "'{$column->name()}' => "; $definition .= sprintf('factory(%s::class)', '\\' . $model->fullyQualifiedNamespace() . '\\' . $class); diff --git a/tests/Feature/Generator/FactoryGeneratorTest.php b/tests/Feature/Generator/FactoryGeneratorTest.php index 680062af..7c0cc3e0 100644 --- a/tests/Feature/Generator/FactoryGeneratorTest.php +++ b/tests/Feature/Generator/FactoryGeneratorTest.php @@ -149,7 +149,7 @@ public function modelTreeDataProvider() ['definitions/unconventional.bp', 'database/factories/TeamFactory.php', 'factories/unconventional.php'], ['definitions/model-modifiers.bp', 'database/factories/ModifierFactory.php', 'factories/model-modifiers.php'], ['definitions/model-key-constraints.bp', 'database/factories/OrderFactory.php', 'factories/model-key-constraints.php'], -// ['definitions/unconventional-foreign-key.bp', 'database/factories/StateFactory.php', 'factories/unconventional-foreign-key.php'], + ['definitions/unconventional-foreign-key.bp', 'database/factories/StateFactory.php', 'factories/unconventional-foreign-key.php'], ]; } } diff --git a/tests/fixtures/definitions/unconventional-foreign-key.bp b/tests/fixtures/definitions/unconventional-foreign-key.bp index 00a8af9d..7cfd1f2a 100644 --- a/tests/fixtures/definitions/unconventional-foreign-key.bp +++ b/tests/fixtures/definitions/unconventional-foreign-key.bp @@ -1,4 +1,7 @@ models: State: name: string - country_code: string foreign:countries.code + countries_id: id foreign:countries + country_code: string foreign:countries + ccid: string foreign:countries + c_code: string foreign:countries.code diff --git a/tests/fixtures/factories/unconventional-foreign-key.php b/tests/fixtures/factories/unconventional-foreign-key.php index 890f750c..248406e3 100644 --- a/tests/fixtures/factories/unconventional-foreign-key.php +++ b/tests/fixtures/factories/unconventional-foreign-key.php @@ -8,8 +8,15 @@ $factory->define(State::class, function (Faker $faker) { return [ 'name' => $faker->name, + 'countries_id' => factory(\App\Country::class), 'country_code' => function () { return factory(\App\Country::class)->create()->code; }, + 'ccid' => function () { + return factory(\App\Country::class)->create()->ccid; + }, + 'c_code' => function () { + return factory(\App\Country::class)->create()->code; + }, ]; }); diff --git a/tests/fixtures/migrations/unconventional-foreign-key.php b/tests/fixtures/migrations/unconventional-foreign-key.php index 1276c028..2aa754b3 100644 --- a/tests/fixtures/migrations/unconventional-foreign-key.php +++ b/tests/fixtures/migrations/unconventional-foreign-key.php @@ -16,8 +16,13 @@ public function up() Schema::create('states', function (Blueprint $table) { $table->id(); $table->string('name'); + $table->foreignId('countries_id')->constrained('countries')->cascadeOnDelete(); $table->string('country_code'); $table->foreign('country_code')->references('code')->on('countries')->onDelete('cascade'); + $table->string('ccid'); + $table->foreign('ccid')->references('ccid')->on('countries')->onDelete('cascade'); + $table->string('c_code'); + $table->foreign('c_code')->references('code')->on('countries')->onDelete('cascade'); $table->timestamps(); }); }