Laravel 10中工厂生成的Item的parent_id始终为null如何解决?
修复Laravel 10中Seeder生成parent_id为空的问题
问题原因
当你使用Item::factory()->count(20)->create()批量创建模型时,Laravel会先一次性调用20次definition()方法生成所有属性数组,再批量插入数据库。这意味着第一次执行$items = Item::all()时数据库里还没有任何Item,后续19次调用时,虽然已经生成了属性数组,但数据库仍未插入数据,所以$items始终为空,最终所有条目的parent_id都是null。
解决方案
方法一:循环逐个创建模型
修改ItemSeeder.php中的代码,将批量创建改为循环逐个调用create(),这样每次创建前都会重新查询已存在的Item:
// 替换原来的 Item::factory()->count(20)->create(); for ($i = 0; $i < 20; $i++) { Item::factory()->create(); }
每次调用create()时,都会实时执行definition()方法,此时$items = Item::all()会包含之前已经插入到数据库的Item,就能正确生成非空的parent_id。
方法二:使用闭包延迟获取parent_id
修改Factory的definition()方法,将parent_id的赋值改为闭包,确保每个模型创建时都重新查询当前数据库中的Item:
<?php use App\Models\Item; use App\Models\User; public function definition() { return [ 'parent_id' => function () { $items = Item::all(); if ($items->isNotEmpty() && rand(1, 3) >= 2) { return $items->random()->id; } return null; }, // 优化user_id获取方式,避免查询所有User 'user_id' => User::inRandomOrder()->first()->id, // 其他字段... ]; }
闭包会在每个模型插入数据库前执行,此时之前创建的Item已经存入数据库,所以$items能正确获取到已存在的条目,从而生成有效的parent_id。
内容的提问来源于stack exchange,提问作者Petro Gromovo
相关产品推荐
相关产品推荐

