[英]Laravel 8 Dynamic Model Factories?
I'm trying to create a package that allows for specifying model factory definitions inside of the model class itself.我正在尝试创建一个 package,它允许在 model class 本身内部指定 model 工厂定义。
For example:例如:
class User extends Authenticatable
{
use LaravelUIModel, Notifiable;
protected $hidden = ['password', 'remember_token'];
protected $casts = ['email_verified_at' => 'datetime'];
public function definition(Generator $faker)
{
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
}
So I created a trait called LaravelUIModel
, where I'm trying to specify a dynamic newFactory
:所以我创建了一个名为
LaravelUIModel
的特征,我试图在其中指定一个动态的newFactory
:
trait LaravelUIModel
{
use HasFactory;
protected static function newFactory()
{
$factory = new Factory;
$factory->setModel(static::class);
return $factory->new();
}
}
Now, the $model
factory properted is protected, so I made my own Factory
class to extend the Eloquent Factory
class, which should allow me to change it:现在,
$model
工厂属性受到保护,所以我创建了自己的Factory
class 来扩展 Eloquent Factory
class,这应该允许我更改它:
class Factory extends EloquentFactory
{
public function setModel($model)
{
$this->model = $model;
}
public function definition()
{
return app($this->model)->definition($this->faker);
}
}
I keep getting this error:我不断收到此错误:
Class "App\" not found
It's like it isn't recognizing that I've set the model name at all, because when I print $this->model
it shows me App\Models\User
.就好像它根本没有意识到我已经设置了 model 名称,因为当我打印
$this->model
时,它会显示App\Models\User
。
How do I set the factory $model dynamically like this so I can specify definitions in the model class, WITHOUT making a new factory file per model?如何像这样动态设置工厂 $model,以便我可以在 model class 中指定定义,而无需根据 model 创建新的工厂文件?
i got this working by creating this trait:我通过创建此特征来实现此功能:
use Faker\Generator;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
trait HasNewFactory
{
use HasFactory;
protected static function newFactory()
{
$factory = new class extends Factory
{
public static $definition;
public function definition()
{
$definition = static::$definition;
return $definition($this->faker);
}
};
$factory::guessModelNamesUsing(function () {
return get_called_class();
});
$factory::$definition = function (Generator $faker) {
return (new static)->definition($faker);
};
return $factory;
}
}
Now in my model, instead of using HasFactory
, I use this HasNewFactory
trait:现在在我的 model 中,我没有使用
HasFactory
,而是使用了这个HasNewFactory
特性:
use Diontron\Lucid\Traits\HasNewFactory;
use Faker\Generator;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
class MyModel extends Model
{
use HasNewFactory;
public function definition(Generator $faker)
{
return [
'name' => $faker->name(),
];
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.