Laravel Seeder仅插入1条数据,预期需插入2500条的问题
Laravel Seeder仅插入1条Post记录问题
问题情况
配置Seeder和Factory后,预期插入2500条Post记录,但实际仅插入1条。尝试过两种指定数量的方式均无效:
- 直接在Factory构造时传入数量:
Post::factory(self::NUMBER_OF_FAKE_POSTS)->create(); - 使用
count()方法指定数量:Post::factory()->count(self::NUMBER_OF_FAKE_POSTS)->create();
相关代码
Factory代码
public function definition(): array { $timestamp = $this->getFakeTimestamp(); return [ 'title' => $this->faker->sentence(), 'body' => $this->faker->paragraph(), 'more_inside' => $this->faker->paragraph(), 'subsite_id' => (new Subsite())->inRandomOrder()->first(), 'user_id' => (new User())->inRandomOrder()->first(), 'created_at' => $timestamp, 'published_at' => $timestamp, 'updated_at' => null, 'deleted_at' => null, 'is_published' => true, 'state' => PostStateEnum::Published->value, ]; }
Seeder代码
final class FakePostSeeder extends Seeder { private const int NUMBER_OF_FAKE_POSTS = 2500; public function run(): void { DB::connection()->disableQueryLog(); Post::factory(self::NUMBER_OF_FAKE_POSTS)->create(); } }
尝试过的count写法
public function run(): void { DB::connection()->disableQueryLog(); Post::factory() ->count(self::NUMBER_OF_FAKE_POSTS) ->create(); }
问题原因
问题出在subsite_id和user_id的赋值逻辑上:(new Subsite())->inRandomOrder()->first()返回的是Subsite模型实例,而非字段需要的ID值。将模型实例直接赋值给整数类型的subsite_id/user_id字段,会导致数据库插入异常。批量插入时,第一条记录可能因隐式转换侥幸成功,但后续记录因类型不匹配被静默拦截,最终仅插入1条。
解决方案
修改Factory中subsite_id和user_id的赋值,明确获取模型的ID:
方案1:直接获取ID
public function definition(): array { $timestamp = $this->getFakeTimestamp(); return [ 'title' => $this->faker->sentence(), 'body' => $this->faker->paragraph(), 'more_inside' => $this->faker->paragraph(), 'subsite_id' => Subsite::inRandomOrder()->first()->id, 'user_id' => User::inRandomOrder()->first()->id, 'created_at' => $timestamp, 'published_at' => $timestamp, 'updated_at' => null, 'deleted_at' => null, 'is_published' => true, 'state' => PostStateEnum::Published->value, ]; }
方案2:用闭包延迟查询(更灵活)
public function definition(): array { $timestamp = $this->getFakeTimestamp(); return [ 'title' => $this->faker->sentence(), 'body' => $this->faker->paragraph(), 'more_inside' => $this->faker->paragraph(), 'subsite_id' => fn () => Subsite::inRandomOrder()->first()->id, 'user_id' => fn () => User::inRandomOrder()->first()->id, 'created_at' => $timestamp, 'published_at' => $timestamp, 'updated_at' => null, 'deleted_at' => null, 'is_published' => true, 'state' => PostStateEnum::Published->value, ]; }
方案3:预加载ID列表(性能更优)
如果需要生成大量数据,先一次性获取所有可用ID,后续随机选取,减少数据库查询次数:
class PostFactory extends Factory { protected $model = Post::class; private array $subsiteIds; private array $userIds; public function __construct(Faker $faker) { parent::__construct($faker); $this->subsiteIds = Subsite::pluck('id')->toArray(); $this->userIds = User::pluck('id')->toArray(); } public function definition(): array { $timestamp = $this->getFakeTimestamp(); return [ 'title' => $this->faker->sentence(), 'body' => $this->faker->paragraph(), 'more_inside' => $this->faker->paragraph(), 'subsite_id' => $this->faker->randomElement($this->subsiteIds), 'user_id' => $this->faker->randomElement($this->userIds), 'created_at' => $timestamp, 'published_at' => $timestamp, 'updated_at' => null, 'deleted_at' => null, 'is_published' => true, 'state' => PostStateEnum::Published->value, ]; } }
内容的提问来源于stack exchange,提问作者kirkaracha
相关产品推荐
相关产品推荐

