0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LaravelでRoute::resourceでバインディングするモデルのキーを変更する

Last updated at Posted at 2022-04-04

前提とRoute model Bindingとは

ルーティングでidなどを指定して受け取るのを、Controllerに来た時点でモデルインスタンスを受け取れる

Route::get('{id}', function($id) {
    Post::find($id);
});

// ↓↓↓↓↓↓

Route::get('{photo}', function(Photo $photo) {

});

Route::resourceRoute::apiResourceというのがあり、これはCRUD系のルートを一括定義してくれる。

動詞 URI アクション ルート名
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos store photos.store
GET /photos/{photo} show photos.show
GET /photos/{photo}/edit edit photos.edit
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy

※上記はRoute::resourceの定義されるもの

これらは定義されたルートを見るとわかるように、コントローラー側で下記のように記述することで対象のモデルを受け取れる
ルートモデルバインディングは基本的にプライマリーキーで処理される

// PhotoのPKがidなのでidで検索され取得されたモデルが渡ってくる
public function show(Photo $photo)
{

}

idで検索されるがカスタマイズもできる

1

web.php
Route::get('/photos/{photo:slug}', function(Photo $photo) {

});

2

Photo.php
/**
 * モデルのルートキーの取得
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

3

AppServiceProvider.php
public function boot()
{
    Route::bind('photo', function ($value) {
        return Photo::where('slug', $value)->firstOrFail();
    });
}

しかし1番目はRoute::resourceRoute::apiResourceでは使えない

2、3番目はRoute::resourceRoute::apiResourceでも基本的に問題ないが、全体が変更される。
常に指定したバインドされる際にキーが使われる。
例えば、ユーザー側と管理側と分ける場合、どちらも指定したキーでバインドすることを意識する必要がある。

やりたいこと

1番目のように、ルートごとに明示したキーを使用したい。

やりかた

scopedを使う。

本来下記のように、ネストしたリソースを定義し子リソースを取得するフィールド指定するときにscopedメソッドを使用します。
そもそもドキュメントにもそのような用途での記述でした
https://laravel.com/docs/9.x/controllers#restful-scoping-resource-routes

web.php
use App\Http\Controllers\PhotoCommentController;

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

しかしこれはネストしていなくても使用できます

web.php
use App\Http\Controllers\PhotoCommentController;

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

これでこのルートだけは、指定したキーを使用してモデルを取得できるようになりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?