簡體   English   中英

Laravel 7 - 嵌套資源路由中的作用域問題

[英]Laravel 7 - Scoping problem in Nested Resource Route

路線:

我有一個這樣的嵌套資源路由定義:

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 model:

public function comments()
{
    return $this->hasMany(Comment::class);
}

Comment model:

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 |
+----+---------+-----------------------------+---------------------+---------------------+

文檔中:

當使用自定義鍵控隱式綁定作為嵌套路由參數時,Laravel 將自動 scope 查詢以檢索其父級使用約定猜測父級關系名稱的嵌套 model。

所以, {comment}應該是{post}的孩子。 但是當我點擊/posts/1/comments/2時,它會檢索 id 為2評論,該評論屬於 id 為2帖子 預期結果將是NotFoundHttpException

當我像這樣單獨定義路由時,它工作正常:

Route::get('/posts/{post}/comments/{comment:id}', 'CommentController@show');

為什么會這樣?

還嘗試在PostComment模型中自定義默認鍵名:

public function getRouteKeyName()
{
    return 'id';
}

但沒有運氣。

任何幫助,將不勝感激。

源代碼中閱讀Illuminate\Routing\PendingResourceRegistration.php class 后做了一些挖掘並得出結論。 我必須使用自定義鍵控隱式綁定才能使其按預期工作。

Route::resource()方法接受(可選的)第三個參數,它是一個關聯數組。 因此,我需要使用此參數通過parameters鍵覆蓋路由參數名稱。

Route::resource('posts.comments', 'CommentController', [
    'parameters' => ['comments' => 'comment:id'],
]);

要么

Route::resource('posts.comments', 'CommentController')->parameters([
    'comments' => 'comment:id',
]);

無論哪種方式都有效。

Laravel 8 和 9

為了實現您的目標,您可以使用 laravel scope 資源路由功能。 例如:

use App\Http\Controllers\PhotoCommentController;
 
Route::resource('photos.comments', PhotoCommentController::class)->scoped([
    'comment' => 'slug',
]);

如果您不想使用自定義密鑰,請將 slug 更改為 id。 請參閱此處的文檔。 您還可以嘗試以下操作:

use App\Http\Controllers\PhotoCommentController;
 
Route::resource('photos.comments', PhotoCommentController::class)->scoped();

您可以在此處找到作用域方法的來源。

Route::resource('photos.comments', PhotoCommentController::class)->scoped([
    'comment' => 'slug',
]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM