Laravel 8 存储数据时外键字段无法正常保存问题排查
问题根因
你提交的请求字段和数据库存储的外键字段名不匹配,同时字段类型不符合设计要求,导致ORM写入时自动忽略了不匹配的字段:
- 表单提交的
authors、genres是数组类型,而books表的外键author_id、genre_id是单值字段 - 校验后的数组键名和
Book模型$fillable中声明的可写字段名完全不对应,create方法会自动过滤不存在于$fillable的字段
修复步骤
1. 修改表单字段命名(create.blade.php)
去掉select标签的数组命名后缀,修改为和外键一致的字段名:
<!-- 作者下拉框 --> <select name="author_id"> @foreach($authors as $author) <option value="{{ $author->id }}">{{ $author->name }}</option> @endforeach </select> <!-- 分类下拉框 --> <select name="genre_id"> @foreach($genres as $genre) <option value="{{ $genre->id }}">{{ $genre->title }}</option> @endforeach </select>
2. 调整控制器校验逻辑(BookController的store方法)
修改校验规则为对应外键字段,增加exists校验避免写入非法关联ID:
public function store(Request $request) { $validatedData = $request->validate([ 'title' => 'required|max:255', 'author_id' => 'required|exists:authors,id', 'genre_id' => 'required|exists:genres,id', 'blurb' => 'required', ]); Book::create($validatedData); return redirect()->route('admin.book.create'); }
3. 修正模型关联命名(可选,建议调整避免后续关联调用出错)
Laravel关联方法遵循单数/复数约定,调整后更符合框架默认规范:
// Book模型修改 class Book extends Model { use HasFactory; protected $fillable = [ 'author_id', 'genre_id', 'title', 'blurb', ]; // 单数命名:一本书属于一个作者 public function author() { return $this->belongsTo(Author::class); } // 单数命名:一本书属于一个分类 public function genre() { return $this->belongsTo(Genre::class); } } // Author模型修改 public function books() { return $this->hasMany(Book::class); } // Genre模型修改 public function books() { return $this->hasMany(Book::class); }
内容的提问来源于stack exchange,提问作者aminke
相关产品推荐
相关产品推荐

