Laravel:如何绑定软删除模型与路由并显示关联评论
问题原因
出现404的核心原因是Laravel路由模型绑定默认会自动过滤掉软删除的模型。当你注入Article $article时,框架会执行类似Article::where('slug', $slug)->firstOrFail()的查询,软删除的文章会被排除,所以直接返回404,根本走不到后面的评论关联判断逻辑。
解决方案
下面提供几种可行的解决方式,你可以根据业务场景选择:
方式一:在路由中指定查询包含软删除的文章
直接在路由定义时,通过withTrashed()指定允许软删除的模型:
// 示例路由定义 Route::get('/articles/{article:slug}/comments/{comment}', [CommentController::class, 'show']) ->withTrashed(['article']); // 允许article参数包含软删除的记录
这样框架注入Article $article时,会自动执行Article::withTrashed()->where('slug', $slug)->firstOrFail(),就能获取到软删除的文章了。
方式二:自定义Article模型的路由绑定逻辑
如果业务中多数场景需要通过路由访问软删除的文章,可以在Article模型里重写路由绑定方法,让它默认包含软删除记录:
// app/Models/Article.php public function resolveRouteBinding($value, $field = null) { return $this->where($field ?? $this->getRouteKeyName(), $value) ->withTrashed() // 包含软删除的记录 ->firstOrFail(); }
注意:这种方式全局生效,所有使用路由模型绑定的Article都会包含软删除记录,若其他场景不需要,谨慎使用。
方式三:使用嵌套模型绑定(更优雅)
如果Article模型已定义和Comment的关联关系:
// app/Models/Article.php public function comments() { return $this->hasMany(Comment::class); }
可以利用Laravel的嵌套隐式模型绑定,同时处理软删除和关联验证:
- 修改路由定义,使用嵌套关联参数:
Route::get('/articles/{article:slug}/comments/{article.comment}', [CommentController::class, 'show']) ->withTrashed(['article']);
- 简化控制器的show方法,无需手动判断关联:
public function show(Article $article, Comment $comment) { return $this->success(['comment' => $comment]); // 修正原代码的语法错误:引号位置 }
这种方式下,Laravel会自动验证评论属于该文章(包括软删除的文章),不匹配则直接返回404,代码更简洁。
额外修复:原代码的语法错误
你的返回语句存在语法错误,['comment => $comment']应改为['comment' => $comment],否则会返回键名格式错误的数组。
内容的提问来源于stack exchange,提问作者BoboBoy
相关产品推荐
相关产品推荐

