Laravel 8中保存赛事至数据库后重定向至赛事详情页的实现问题
Laravel 8: 保存赛事后重定向至详情页的正确实现
问题背景
我在Laravel 8框架下开发赛事相关功能,希望在将赛事数据保存到数据库后,重定向至新创建的赛事详情页面。目前使用return redirect()->route('tournaments.show', $tournament->slug);代码无法实现该需求,当前控制器的store方法最后返回的是redirect()->back();,控制器代码如下:
public function store(Request $request) { $tournament = new Tournament(); $tournament->title = $request->title; $tournament->city = $request->city; $tournament->street = $request->street; $tournament->game_room = $request->game_room; $tournament->email = $request->email; $tournament->registration_link = $request->registration_link; $tournament->text = $request->text; $tournament->phone = $request->phone; $tournament->time_registration_at = $request->time_registration_at; $tournament->date_registration_at = $request->date_registration_at; $tournament->time_starter_at = $request->time_starter_at; $tournament->date_starter_at = $request->date_starter_at; $tournament->user_id = Auth::user()->id; $tournament->region_id = $request->region_id; $tournament->slug = SlugService::createSlug(Tournament::class, 'slug', $request->title); $tournament->save(); return redirect()->back(); }
解决方案
你遇到的问题通常是路由定义不匹配或者参数传递格式不正确导致的,按照以下步骤调整即可:
1. 确保路由定义正确(关键!)
在routes/web.php中,你的赛事详情路由必须明确指定用slug作为路由参数的匹配字段,否则Laravel会默认使用模型的id字段去查找资源,导致找不到刚创建的赛事。正确的路由写法如下:
// 使用路由模型绑定,指定slug作为匹配字段 Route::get('/tournaments/{tournament:slug}', [TournamentController::class, 'show'])->name('tournaments.show');
2. 修改控制器的store方法重定向逻辑
替换原来的return redirect()->back();,改为传递正确的参数到路由。注意要确保赛事数据已经成功保存(save()方法返回布尔值,可以做个简单判断):
public function store(Request $request) { $tournament = new Tournament(); $tournament->title = $request->title; $tournament->city = $request->city; $tournament->street = $request->street; $tournament->game_room = $request->game_room; $tournament->email = $request->email; $tournament->registration_link = $request->registration_link; $tournament->text = $request->text; $tournament->phone = $request->phone; $tournament->time_registration_at = $request->time_registration_at; $tournament->date_registration_at = $request->date_registration_at; $tournament->time_starter_at = $request->time_starter_at; $tournament->date_starter_at = $request->date_starter_at; $tournament->user_id = Auth::user()->id; $tournament->region_id = $request->region_id; $tournament->slug = SlugService::createSlug(Tournament::class, 'slug', $request->title); // 确认数据保存成功后再重定向 if ($tournament->save()) { // 传递slug参数到路由,注意参数名要和路由中的{tournament:slug}对应 return redirect()->route('tournaments.show', ['tournament' => $tournament->slug]); } // 保存失败时返回上一页并携带错误提示 return redirect()->back()->with('error', '赛事创建失败,请重试'); }
3. 可选:模型中指定路由主键(简化操作)
如果你希望所有和Tournament相关的路由都默认使用slug作为主键,可以在Tournament模型中添加以下方法,这样路由模型绑定时会自动用slug匹配:
// app/Models/Tournament.php public function getRouteKeyName() { return 'slug'; }
添加这个方法后,你甚至可以简化重定向的代码,直接传递整个模型实例:
return redirect()->route('tournaments.show', $tournament);
常见排查点
- 检查
SlugService::createSlug()生成的slug是否唯一且有效,避免因为slug重复导致的404错误; - 确认路由名称
tournaments.show拼写完全正确(大小写敏感); - 确保
show方法能正确接收并通过slug查询到赛事模型,比如show方法的代码应该类似:
public function show(Tournament $tournament) { return view('tournaments.show', compact('tournament')); }
内容的提问来源于stack exchange,提问作者Tom_hutka
相关产品推荐
相关产品推荐

