Laravel 7 - 嵌套资源路由中的范围问题
Posted
技术标签:
【中文标题】Laravel 7 - 嵌套资源路由中的范围问题【英文标题】:Laravel 7 - Scoping problem in Nested Resource Route 【发布时间】:2020-11-18 22:00:44 【问题描述】:路线:
我有一个这样的嵌套资源路由定义:
Route::resource('posts.comments', 'CommentController');
这会产生以下路线:
+--------+-----------+--------------------------------------+------------------------+------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+--------------------------------------+------------------------+------------------------------------------------+------------+
| | GET|HEAD | posts/post/comments | posts.comments.index | App\Http\Controllers\CommentController@index | web |
| | POST | posts/post/comments | posts.comments.store | App\Http\Controllers\CommentController@store | web |
| | GET|HEAD | posts/post/comments/create | posts.comments.create | App\Http\Controllers\CommentController@create | web |
| | GET|HEAD | posts/post/comments/comment | posts.comments.show | App\Http\Controllers\CommentController@show | web |
| | PUT|PATCH | posts/post/comments/comment | posts.comments.update | App\Http\Controllers\CommentController@update | web |
| | DELETE | posts/post/comments/comment | posts.comments.destroy | App\Http\Controllers\CommentController@destroy | web |
| | GET|HEAD | posts/post/comments/comment/edit | posts.comments.edit | App\Http\Controllers\CommentController@edit | web |
+--------+-----------+--------------------------------------+------------------------+------------------------------------------------+------------+
关系(在模型中):
Post
模特:
public function comments()
return $this->hasMany(Comment::class);
Comment
模特:
public function post()
return $this->belongsTo(Post::class);
虚拟数据(在表格中):
posts
表:
+----+--------+-----------------------------+---------------------+---------------------+
| id | title | body | created_at | updated_at |
+----+--------+-----------------------------+---------------------+---------------------+
| 1 | Post 1 | This is the body of Post 1. | 2020-07-29 11:20:53 | 2020-07-29 11:20:53 |
| 2 | Post 2 | This is the body of Post 2. | 2020-07-29 11:21:13 | 2020-07-29 11:21:13 |
+----+--------+-----------------------------+---------------------+---------------------+
comments
表:
+----+---------+-----------------------------+---------------------+---------------------+
| id | post_id | body | created_at | updated_at |
+----+---------+-----------------------------+---------------------+---------------------+
| 1 | 1 | The comment for the Post 1. | 2020-07-29 11:22:27 | 2020-07-29 11:22:27 |
| 2 | 2 | The comment for the Post 2. | 2020-07-29 11:22:32 | 2020-07-29 11:22:32 |
+----+---------+-----------------------------+---------------------+---------------------+
在docs:
当使用自定义键控隐式绑定作为嵌套路由时 参数,Laravel 将自动限定查询范围以检索 由其父级嵌套模型使用约定来猜测关系 父母的名字。
所以,comment
应该是 post
的子级。但是当我点击/posts/1/comments/2
时,它会检索 ID 为 2 的 comment,它属于 ID 为 2 的 post 。预期结果为NotFoundHttpException
。
当我像这样单独定义路由时,它工作正常:
Route::get('/posts/post/comments/comment:id', 'CommentController@show');
为什么会这样?
还尝试在Post
和Comment
模型中自定义默认键名:
public function getRouteKeyName()
return 'id';
但没有运气。
任何帮助将不胜感激。
【问题讨论】:
似乎只有在使用自定义键控隐式绑定时才会发挥作用......如果您愿意,您可以扩展 ResourceRegistrar 以将此信息添加到它定义的路由中,如果您真的想要use App\Post; use App\Comment; Route::get('posts/post/comments/comment:id', function (Post $post, Comment $comment) return $comment; );
试试,如果你得到数据,你在CommentController@show
有问题
@xNoJustice 我已经尝试过这种方式。但我有一个嵌套的资源路由定义。
添加一个控件到CommentController@show
以解决您的问题。$comment = Comment::where('post_id',$post)->where('id', $comment)->get();
此控件会导致在选择错误帖子时返回错误。
【参考方案1】:
在阅读source code 中的Illuminate\Routing\PendingResourceRegistration.php
类后进行了一些挖掘并得出了结论。 我必须使用自定义键控隐式绑定才能使其按预期工作。
Route::resource()
方法采用(可选)第三个参数,它是一个关联数组。所以,我需要使用这个参数通过parameters
键覆盖路由参数名称。
Route::resource('posts.comments', 'CommentController', [
'parameters' => ['comments' => 'comment:id'],
]);
或
Route::resource('posts.comments', 'CommentController')->parameters([
'comments' => 'comment:id',
]);
无论哪种方式都可以。
【讨论】:
以上是关于Laravel 7 - 嵌套资源路由中的范围问题的主要内容,如果未能解决你的问题,请参考以下文章