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

Laravel 10多关联模型Factory与Seeder填充数据报错求助

Laravel 多表关联迁移与数据填充错误解决

问题背景

  • 涉及三个数据表:Categories、Books、Authors
  • 关联关系:
    • Categories 与 Books 为一对多
    • Authors 与 Books 为一对多
  • 先完成了Categories和Books的迁移、模型及数据填充,后添加Authors相关文件后,执行迁移和Seeder时出现两个错误:

    SQLSTATE[HY000]: General error: 1005 Can't create table booky.books (errno: 150 "Foreign key constraint is incorrectly formed") (Connection: mysql, SQL: alter table books add constraint books_author_id_foreign foreign key (author_id) references authors (id) on delete cascade)
    SQLSTATE[HY000]: General error: 1364 Field 'author_id' doesn't have a default value

错误原因分析

  1. 外键约束错误:
    原Books迁移文件中直接添加了author_id外键,但执行该迁移时Authors表尚未创建,MySQL无法创建指向不存在表的外键约束。
  2. 字段缺失默认值错误:
    创建Book时未提供author_id值(原Seeder仅传入category_id),且author_id字段无默认值,违反数据库非空约束。

解决方案

1. 修复迁移文件

如果已经执行过Books的迁移,不要直接修改原迁移文件,而是创建新迁移来添加author_id字段及外键:

php artisan make:migration add_author_id_to_books_table

在新迁移文件中写入:

public function up(): void
{
    Schema::table('books', function (Blueprint $table) {
        // 添加author_id字段,自动关联authors表并设置级联删除
        $table->foreignId('author_id')->constrained()->cascadeOnDelete();
    });
}

public function down(): void
{
    Schema::table('books', function (Blueprint $table) {
        $table->dropForeign(['author_id']);
        $table->dropColumn('author_id');
    });
}

注意:确保Authors迁移文件的时间戳前缀早于这个新迁移文件,让Authors表先被创建。如果Authors迁移是后创建的,手动调整文件名的时间戳即可。

2. 完善模型关联

  • 在App\Models\Book中添加关联:
public function category()
{
    return $this->belongsTo(Category::class);
}

public function author()
{
    return $this->belongsTo(Author::class);
}
  • 在App\Models\Author中添加关联:
public function books()
{
    return $this->hasMany(Book::class);
}
  • 在App\Models\Category中添加关联:
public function books()
{
    return $this->hasMany(Book::class);
}

3. 调整Book Factory

修改BookFactory,让它自动关联Author,避免手动传值:

public function definition(): array
{
    return [
        'book_title' => fake()->sentence(),
        'book_desc' => fake()->paragraph(),
        'book_image' => fake()->imageUrl(),
        // 自动关联随机存在的作者
        'author_id' => \App\Models\Author::inRandomOrder()->first()->id
    ];
}

4. 优化DatabaseSeeder

先创建所有分类和作者,再批量创建书籍并关联两者,逻辑更清晰:

public function run(): void
{
    // 先创建3个分类
    $categories = \App\Models\Category::factory(3)->create();
    // 先创建5个作者
    $authors = \App\Models\Author::factory(5)->create();

    // 为每个分类创建4本书,同时关联随机作者
    $categories->each(function ($category) use ($authors) {
        \App\Models\Book::factory(4)->create([
            'category_id' => $category->id,
            'author_id' => $authors->random()->id
        ]);
    });
}

验证执行

  1. 回滚之前的错误迁移(若需要):
php artisan migrate:rollback
  1. 重新执行迁移:
php artisan migrate
  1. 运行Seeder:
php artisan db:seed

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 21:33:11