darmats's avatar

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';
});
0 likes
0 replies

Please or to participate in this conversation.