so when using the new model factories class introduced in laravel 8.x, ive this weird issue saying that laravel cannot find the factory that corresponds to the model. i get
You need to ensure that the namespace is the same: as shown below: otherwise this will screw you up big time. The name of the factory is the name of the model
+ Factory
e.g. app\models\User
- will match to database/factories/UserFactory
finally ensure you run: composer dumpautoload
Today I have got below issue after upgrading my project from Laravel 7
to Laravel 8
and updating it online on server.
Trait 'Illuminate\Database\Eloquent\Factories\HasFactory' not found
Even I have updated composer.json
with autoload directive given in answer by @lagbox but it did not resolved the issue for me.
Finally I have updated complete vendors folder online that have resolved my issue.
Hope it helps someone in future!
I'm in the process of migrating from laravel 7 to 8.
After banging my head against the wall for a while and looking at the source code, I saw that you can optionally override what factory class gets called for a model using the newFactory
method on the model.
I also then noticed that it IS in the documentation (https://laravel.com/docs/8.x/database-testing#creating-models) - I just didn't understand what it meant the first time I read it. Now I do.
I solved this by the following:
<?php
namespace My\Fancy\Models;
use Database\Factories\SomeFancyFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SomeClass extends Model
{
use HasFactory;
/** @return SomeFancyFactory */
protected static function newFactory()
{
return SomeFancyFactory::new();
}
}
After this change, my tests passed as expected.
I was having this same issue, but for a different reason. If you're using factories in the setUp
function of a test, make sure:
Tests\TestCase
(instead of PHPUnit\Framework\TestCase
)setUp
function should be parent::setUp();
(I was missing this)Apparently you have to respect the folder structure as well. For example, if you have the User Model in the following path: app\Models\Users\User
, then the respective factory should be located in database\factories\Users\UserFactory
.
If you upgraded to 8 from a previous version you are probably missing the autoload directive for the Database\Factories
namespace in composer.json
:
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
You can also remove the classmap
part, since it is no longer needed.
Run composer dump
after making these changes.
Laravel 8.x Docs - Upgrade Guide - Database - Seeder and Factory Namespace