The Database Factory namespace does not behave as expected when "App\\" is included in the Model namespace
First, my project has a temporary workaround for the following issue.
However, I would like to ask whether this should be fixed as a bug in the framework.
Versions
- PHP: 8.3.11
- Laravel: 11.29.0
Details
In addition to the "app" directory, my Laravel project has the following directory structure:
.
├── app
│ ├── ...
├── database
│ └── factories
│ └── Feature
│ └── FooApp
│ └── Models
│ └── UserFactory.php
├── feature
│ └── FooApp
│ └── Models
│ └── User.php
PSR-4 configuration in composer.json:
{
"psr-4": {
"App\\": "app/",
"Feature\\": "feature/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
}
The content of User.php:
<?php
namespace Feature\FooApp\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use HasFactory;
}
The content of UserFactory.php:
<?php
namespace Database\Factories\Feature\FooApp\Models;
use Feature\FooApp\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition(): array
{
return [];
}
}
In this setup, I expect the Factory class for Feature\FooApp\Models\User to resolve to Database\Factories\Feature\FooApp\Models\UserFactory.
However, it resolves to Database\Factories\Models\UserFactory instead.
If you call Feature\FooApp\Models\User::factory() ,
you will get the error Class "Database\Factories\Models\UserFactory" not found.
I think, this causes issues when there are models with the same name in different namespaces (e.g., Feature\FooApp\Models\User and Feature\BarApp\Models\User ), as it results in duplicate Factory namespaces.
Workaround in my project
Since my project doesn't have any models in 'App', I've written the following code in the boot method of AppServiceProvider:
Factory::guessFactoryNamesUsing(static function (string $modelName) {
return Factory::$namespace . $modelName . 'Factory';
});
Please or to participate in this conversation.