I'm creating a package that will serve as a base for projects, and I'm stuck on the creation of factories. For the package, I use the namespace Gad\Base
.
I created a model MyModel
in src/
:
namespace Gad\Base;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class MyModel extends Model
{
use HasFactory;
protected $guarded = [];
}
and the corresponding factory MyModelFactory
in database/factories/
:
namespace Database\Factories;
use Gad\Base\MyModel;
use Illuminate\Database\Eloquent\Factories\Factory;
class MyModelFactory extends Factory
{
protected $model = MyModel::class;
public function definition()
{
return [
'something' => $this->faker->text(100),
];
}
}
But when I try to use the factory (in a test, for example)
MyModel::factory()->create()
I get the following error:
Error: Class "Database\Factories\Gad\Base\MyModelFactory" not found
I am not sure why looks for Database\Factories\Gad\Base\MyModelFactory
and not for Database\Factories\MyModelFactory
.
This is how I defined my autoload in composer.json
:
"autoload": {
"psr-4": {
"Gad\\Base\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Gad\\Base\\Tests\\": "tests/",
"Database\\Factories\\": "database/factories/"
}
}
If in MyModel
I override the static function newFactory()
like this:
protected static function newFactory()
{
return new MyModelFactory();
}
Everything works fine. Anyone knows what I did wrong?
The answer is in the resolver for factory name Illuminate/Database/Eloquent/Factories/Factory.php@798
It checks if the model is in the namespace
\App\Models\
(or more precisely\$appNamespace\Models\
) like standard models of the app, if not it apprends the namespace of the model and add the suffixFactory
to it.