Eloquent ORM字符串与整数主键多对多关联问题求助
问题分析与解决方案
错误根源
从报错SQL能看到,插入中间表时map_slug的值是0而非创建的Map实际slug字符串。原因是Eloquent默认主键为自增整数类型,即便你在Map模型中设置了$keyType = 'string'和$primaryKey = 'slug',但未关闭自增特性,框架仍会尝试把字符串主键转成整数,最终得到0,触发外键约束失败。
修复步骤
1. 更新Map模型
在Map模型中添加$incrementing = false;,明确告知Eloquent该模型主键不是自增类型:
class Map extends Model { protected $primaryKey = 'slug'; protected $keyType = 'string'; public $incrementing = false; // 新增该行 protected $fillable = [ 'name', 'slug', 'perex', 'categories', 'company', 'icon', 'is_public', 'bounds', ]; public function suppliers(): Collection { return $this->hasMany(Supplier::class)->get(); } public function users(): BelongsToMany { return $this->belongsToMany(User::class, 'map_user', 'map_slug', 'user_id'); } }
2. 优化Store方法(可选)
可简化当前用户获取逻辑,无需重复查询数据库:
/** * Store a newly created resource in storage. */ public function store(StoreMapRequest $request): RedirectResponse { $user = auth()->user(); // 直接获取当前认证用户 $map = Map::create([ 'name' => $request->input('name'), 'slug' => $request->input('slug'), 'perex' => $request->input('perex'), 'categories' => $request->input('categories'), 'company' => $request->enum('company', Company::class), 'icon' => $request->input('icon'), 'is_public' => $request->boolean('isPublic'), 'bounds' => $request->boolean('bounds'), ]); $map->users()->attach($user->id); return to_route('admin.dashboard')->with('success', 'Map created!'); }
验证逻辑
修改后,Eloquent会正确识别Map主键为字符串类型,调用attach()时会传入实际slug值到中间表,外键约束即可正常通过。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

