重构Laravel工厂时报Closure object cannot have properties如何解决?
错误原因
你将$employment声明为了未执行的闭包对象,直接尝试访问闭包的id属性,触发了Closure object cannot have properties报错。
Laravel 8+ 工厂类不需要手动定义闭包接收$attributes参数,你可以直接通过$this->attributes属性获取调用工厂时传入的自定义属性。
修复代码
直接去掉包裹$employment的多余闭包,提前计算出Employment模型实例即可:
public function definition() { $employment = Arr::exists($this->attributes, 'employment_id') ? Employment::where('id', $this->attributes['employment_id'])->first() : Employment::factory()->create(); return [ 'employment_id' => $employment->id, 'calendar_id' => fn () => Calendar::factory()->create([ 'company_id' => $employment->company_id, ]), ]; }
可选优化写法
如果你的工厂逻辑更复杂,需要遵循属性延迟执行规则,可以直接在返回数组的闭包中接收自动注入的属性数组:
public function definition() { return [ 'employment_id' => fn (array $attributes) => Arr::exists($attributes, 'employment_id') ? $attributes['employment_id'] : Employment::factory()->create()->id, 'calendar_id' => fn (array $attributes) => Calendar::factory()->create([ 'company_id' => Employment::find($attributes['employment_id'])->company_id, ]), ]; }
该写法不会提前创建不必要的模型实例,性能更优,适合多字段依赖的复杂工厂场景。
内容的提问来源于stack exchange,提问作者Amithash
相关产品推荐
相关产品推荐

