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
/**
* Get the factory name for the given model name.
*
* @param class-string<\Illuminate\Database\Eloquent\Model> $modelName
* @return class-string<\Illuminate\Database\Eloquent\Factories\Factory>
*/
public static function resolveFactoryName(string $modelName)
{
$resolver = static::$factoryNameResolver ?? function (string $modelName) {
$appNamespace = static::appNamespace();
$modelName = Str::startsWith($modelName, $appNamespace.'Models\\')
? Str::after($modelName, $appNamespace.'Models\\')
: Str::after($modelName, $appNamespace);
return static::$namespace.$modelName.'Factory';
};
return $resolver($modelName);
}
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 suffix Factory
to it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.