Laravel中如何在Lead工厂内获取Company工厂的Fields关联数据?
Laravel中如何在Lead工厂内获取Company工厂的Fields关联数据?
首先咱们得先搞清楚你报错的核心原因:你在Lead工厂里写的$company = Company::factory();,这玩意儿返回的是Company工厂实例,不是真正的Company模型对象!工厂类本身根本没有fields这个属性——毕竟你的fields是在Company模型的created事件里生成的,只有当Company被实际保存到数据库之后,这些fields才会存在。
明白了问题根源,咱们来解决它:
你的Seeder里用了Company::factory(10)->hasLeads(10)->create();,这意味着每个Company会自动关联创建10个Lead,而且Laravel会自动把对应的company_id传递给Lead工厂。所以你完全不需要在Lead工厂里重新创建Company工厂,直接用已经关联好的Company模型就行。
修改后的Lead工厂代码可以这样写:
public function definition(): array { // 通过当前Lead的company_id,找到对应的Company模型(提前预加载fields,避免N+1查询) $company = Company::with('fields')->find($this->company_id); // 先把需要的fields找出来,避免重复调用firstWhere $firstNameField = $company->fields->firstWhere('name', 'First Name'); $lastNameField = $company->fields->firstWhere('name', 'Last Name'); $emailField = $company->fields->firstWhere('name', 'Email Address'); $phoneField = $company->fields->firstWhere('name', 'Phone Number'); return [ // 这里company_id可以不用写,因为hasLeads已经自动帮你设置好了 'fields' => [ $firstNameField->id => fake()->firstName(), $lastNameField->id => fake()->lastName(), $emailField->id => fake()->safeEmail(), $phoneField->id => fake()->phoneNumber(), ], ]; }
如果想让代码更简洁,还可以在Company模型里加个辅助方法,专门通过字段名获取ID:
// 在App\Models\Company里添加 public function getFieldIdByName(string $name): int { return $this->fields->firstWhere('name', $name)->id; }
然后Lead工厂就可以简化成这样:
public function definition(): array { $company = Company::with('fields')->find($this->company_id); return [ 'fields' => [ $company->getFieldIdByName('First Name') => fake()->firstName(), $company->getFieldIdByName('Last Name') => fake()->lastName(), $company->getFieldIdByName('Email Address') => fake()->safeEmail(), $company->getFieldIdByName('Phone Number') => fake()->phoneNumber(), ], ]; }
这样就能完美解决你的问题了——既用到了Observer自动生成的fields,又不会再出现工厂属性未定义的错误。
备注:内容来源于stack exchange,提问作者jdion84
相关产品推荐
相关产品推荐

