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

Laravel 10工厂去重:关联SkillUsed模型的数据库填充问题求助

Laravel 10 事件填充器关联不重复技能解决方案

核心问题分析

你的代码存在两个关键问题:

  • 创建SkillUsed时未传递当前Incident的ID,导致工厂随机关联其他事件,无法绑定到目标事件
  • 批量生成SkillUsed时,工厂内的数据库查询无法实时获取同批次刚创建的技能记录,可能出现重复关联

修改方案

1. 重构填充器代码

在事件创建后的闭包中,直接筛选不重复的技能ID再创建关联,确保逻辑可控:

protected function seedIncidents(): void
{
    Incident::factory()
        ->state(['incident_snr' => 0])
        ->count(50)
        ->create()
        ->each(function ($incident) {
            // 定义可用技能ID(若技能动态维护,可改为 Skill::pluck('sid')->toArray())
            $availableSkillIds = [1, 2, 3];
            // 随机选取1-3个不重复的技能(最多选3个,避免超出可用技能数量)
            $selectedSkillIds = collect($availableSkillIds)
                ->shuffle()
                ->take(fake()->numberBetween(1, 3));
            
            // 为选中的技能创建关联记录
            $selectedSkillIds->each(function ($skillId) use ($incident) {
                SkillUsed::factory()->create([
                    'incident_id' => $incident->id,
                    'sid' => $skillId,
                ]);
            });
        });
}

2. 简化SkillUsed工厂

去掉工厂内复杂的查询逻辑,改为优先使用外部传入的属性,让职责更清晰:

public function definition(array $attributes = []): array
{
    // 优先使用传入的incident_id,否则随机取一个(兼容其他场景)
    $incidentId = $attributes['incident_id'] ?? Incident::inRandomOrder()->value('incident_id');
    // 优先使用传入的sid,否则随机取一个(兼容其他场景)
    $skillId = $attributes['sid'] ?? Skill::inRandomOrder()->value('sid');

    return [
        'sid' => $skillId,
        'incident_id' => $incidentId,
        'deleted_at' => fake()->optional(0.2)->dateTimeBetween('-6 months', 'now'),
    ];
}

方案优势

  • 直接在填充器中控制技能选择逻辑,从根源避免重复关联问题
  • 明确绑定当前事件ID,确保关联关系完全匹配目标事件
  • 工厂职责简化为生成模型默认属性,逻辑更清晰易维护

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 01:04:52