You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Laravel Factory创建各带独立Company的10个Service模型

问题:Laravel工厂创建关联模型时重复使用同一父模型且关联加载为空

需求

创建10个Service模型实例,每个实例对应唯一的Company模型(Service与Company为belongsTo关联)。

当前代码与问题

Service模型关联定义

/**
 * Get the company a specified service belongs to
 *
 * @return BelongsTo
 */
public function company(): BelongsTo
{
    return $this->belongsTo(Company::class);
}

测试代码

Service::factory()
    ->count(10)
    ->create([
        'company_id' => Company::factory()->create(),
    ]);

print_r((Company::all())->toArray());
print_r((Service::with(['company'])->get())->toArray());

测试结果

  • 成功生成10个Service,但所有Service的company_id完全相同,仅生成1个Company
  • 加载company关联时,所有Service的company字段为空

问题原因

  1. 重复使用同一Company:直接传入Company::factory()->create()时,该代码仅执行一次,生成的ID被复用给所有10个Service。
  2. 关联加载为空:使用字符串类型主键时,若未在模型中明确声明主键类型,Eloquent会默认按整数处理主键,导致关联查询不匹配。

解决方案

方案1:使用闭包为每个Service生成独立Company

通过闭包让每个Service创建时都生成新的Company:

Service::factory()
    ->count(10)
    ->create(function () {
        return [
            'company_id' => Company::factory()->create()->id,
        ];
    });

方案2:使用Laravel工厂的for方法(推荐)

利用Laravel工厂的关联语法,更简洁地创建一对一关联的模型:

Service::factory()
    ->count(10)
    ->for(Company::factory()) // 自动为每个Service创建并关联唯一Company
    ->create();

修复关联加载为空的问题

在Company模型中添加字符串主键声明:

class Company extends Model
{
    use SoftDeletes;

    protected $keyType = 'string';
    public $incrementing = false;

    // ... 其他模型代码
}

若Service模型主键也是字符串类型,同样需要添加上述配置。

验证结果

执行修复后的代码后,会生成10个Company和10个一一对应的Service,且Service::with('company')->get()能正常加载关联的Company数据。

内容的提问来源于stack exchange,提问作者BobbyP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:05:22