-
Notifications
You must be signed in to change notification settings - Fork 11.7k
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
$modelNameResolverproperty insrc\Illuminate\Database\Eloquent\Factories\Factory.phpto 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
UseFactoryattribute 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]',
]);