【问题标题】:Laravel factory fails when the model has a constructor当模型有构造函数时,Laravel 工厂失败
【发布时间】:2021-12-27 19:32:12
【问题描述】:

在 Laravel 8 中,当我在具有 __construct 的模型上运行 factory()->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');
    }
}

【问题讨论】:

  • Welcome to SO ... 模型已经定义了一个构造函数,它实际上做了一些事情,你只是覆盖了这个构造函数而不做任何事情(如果你定义了一个不做'不获取属性并填充模型?)...github.com/laravel/framework/blob/8.x/src/Illuminate/Database/…
  • 你至少需要调用父构造函数,否则你的构造函数是空的,因此没用
  • 无论我添加 parent::__construct() 还是 __construct 中的任何其他代码都不会改变任何东西,同样的错误。为了简单起见,我删除了代码……但也许我不应该这样做! ;) 我已经编辑了我的答案以使其更清晰
  • 不仅仅是调用父构造函数。基类 Model 的构造函数签名为 public function __construct(array $attributes = []),因此您应该使构造函数与该签名兼容,并将可选的 $attributes 传递给父类
  • 谢谢布赖恩·汤普森(和其他人)。我知道是这样的,只是找不到。谢谢大家。

标签: laravel constructor factory


【解决方案1】:

为了结束这个问题,我将 Brian Thompson 的答案写在 cmets 中:

“这不仅仅是调用父构造函数。基础模型类具有公共函数__construct(array $attributes = [])的构造函数签名,因此您应该使您的构造函数与该签名兼容并传递可选的$父属性"

所以基本上,我只是将我的构造函数代码更改为:

public function __construct(array $attributes = []) {
    parent::__construct($attributes);
}   

【讨论】:

    猜你喜欢
    • 2021-02-07
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多