Laravel 当模型有构造函数时工厂失败
Laravel factory fails when the model has a constructor
在 Laravel 8 中,当我 运行 在具有 __construct 的模型上创建工厂 ()->create() 时,此代码:
Route::get('/test', function (){
$doc = ClientDocument::factory()->create();
});
失败:
"SQLSTATE[HY000]: General error: 1364 Field 'filename' doesn't have a default value (SQL: insert into `client_documents` (`updated_at`, `created_at`) values (2021-11-16 12:45:20, 2021-11-16 12:45:20))"
如果我删除 __construct,工厂 运行 没问题并保存到数据库中...我在这里缺少什么?谢谢!
型号
class ClientDocument extends Model
{
use HasFactory;
protected $connection = 'mysql';
protected $fillable = ['filename'];
protected $locale;
public function __construct() {
// SET THE LANGUAGE
if ( auth()->user() ) {
$this->locale = auth()->user()->locale;
} else {
$this->locale = 'en';
}
}
}
工厂
class ClientDocumentFactory extends Factory
{
public function definition()
{
$user = User::factory()->create();
$client = $user->createNewClientFile();
return [
'filename' => $this->faker->lexify('????????'),
];
}
}
迁移
class CreateClientDocumentsTable extends Migration
{
public function up()
{
Schema::create('client_documents', function (Blueprint $table) {
$table->id();
$table->string('filename');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('client_documents');
}
}
为了结束这个问题,我把 Brian Thompson 的答案写在评论中:
"这不仅仅是调用父构造函数。基础模型 class 具有 public 函数 __construct(array $attributes = []) 的构造函数签名,因此您应该使您的构造函数与该签名兼容,并将可选的 $attributes 传递给父级
基本上,我只是将构造函数代码更改为:
public function __construct(array $attributes = []) {
parent::__construct($attributes);
}
在 Laravel 8 中,当我 运行 在具有 __construct 的模型上创建工厂 ()->create() 时,此代码:
Route::get('/test', function (){
$doc = ClientDocument::factory()->create();
});
失败:
"SQLSTATE[HY000]: General error: 1364 Field 'filename' doesn't have a default value (SQL: insert into `client_documents` (`updated_at`, `created_at`) values (2021-11-16 12:45:20, 2021-11-16 12:45:20))"
如果我删除 __construct,工厂 运行 没问题并保存到数据库中...我在这里缺少什么?谢谢!
型号
class ClientDocument extends Model
{
use HasFactory;
protected $connection = 'mysql';
protected $fillable = ['filename'];
protected $locale;
public function __construct() {
// SET THE LANGUAGE
if ( auth()->user() ) {
$this->locale = auth()->user()->locale;
} else {
$this->locale = 'en';
}
}
}
工厂
class ClientDocumentFactory extends Factory
{
public function definition()
{
$user = User::factory()->create();
$client = $user->createNewClientFile();
return [
'filename' => $this->faker->lexify('????????'),
];
}
}
迁移
class CreateClientDocumentsTable extends Migration
{
public function up()
{
Schema::create('client_documents', function (Blueprint $table) {
$table->id();
$table->string('filename');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('client_documents');
}
}
为了结束这个问题,我把 Brian Thompson 的答案写在评论中:
"这不仅仅是调用父构造函数。基础模型 class 具有 public 函数 __construct(array $attributes = []) 的构造函数签名,因此您应该使您的构造函数与该签名兼容,并将可选的 $attributes 传递给父级
基本上,我只是将构造函数代码更改为:
public function __construct(array $attributes = []) {
parent::__construct($attributes);
}