-
Notifications
You must be signed in to change notification settings - Fork 11.6k
Description
Laravel Version
11.42.0
PHP Version
8.3.15
Database Driver & Version
No response
Description
The UseFactory
attribute introduced in v11.39.0 causes problems when you create a model with the UseFactory
attribute and then a model that doesn't specify it. The HasFactory
trait calls guessModelNamesUsing
in the Illuminate\Database\Eloquent\Factories\Factory
, which sets a static property that then applies to all classes that inherit Factory
.
The bug ultimately originates from the model name resolver being set in the Factory class. It's setting the $modelNameResolver
property for Factory
and every class that inherits Factory
.
Possible Solutions
- Change the
$modelNameResolver
property insrc\Illuminate\Database\Eloquent\Factories\Factory.php
to an array, which holds a implemented factory class name with a resolver:
protected static $modelNameResolver = [];
// ...
public function modelName()
{
// ...
$resolver = static::$modelNameResolver[static::class] ?? function (self $factory) {
// ...
};
// ...
}
// ...
public static function guessModelNamesUsing(callable $callback)
{
static::$modelNameResolver[static::class] = $callback;
}
- Require the
UseFactory
attribute set for all or none of the models. This would mean updating the documentation.
Steps To Reproduce
The repository is located at: https://github.com/SameOldNick/laravel-factory-bug
Install Steps
- Clone the repo:
git clone https://github.com/SameOldNick/laravel-factory-bug
- Install Composer packages:
composer install
- Create .env file:
cp .env.example .env
- Run PHPUnit test case:
php artisan test --filter=BugTest
Copy of Problem Code
For the record, I've included the problem code. The Role
class has the UseFactory
attribute set, while the User
class doesn't.
// Works fine
Role::factory(5)->create();
// Will try insert into roles table
User::factory()->create([
'name' => 'Test User',
'email' => '[email protected]',
]);