🦁

Laravel Tips集 ~Routing & Request の便利技大全~

2025/02/14に公開

Laravel Routing & Request Tips チートシート 🚀

Laravel のルーティングやリクエスト処理に関する便利なテクニックをまとめました。
ルートモデルバインディング、リダイレクト、ミドルウェアの適用方法など、開発を効率化する様々な Tips を紹介します。


1. フォームリクエストでのモデルバインディング

通常、ルートモデルバインディングはコントローラで使用しますが、フォームリクエストでも route('モデル名') を使って、ルートからモデルインスタンスを取得できます。

<?php

// ルート定義
Route::put('/post/{post}', [PostsController::class, 'create']);

// フォームリクエスト
class PostRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can('create', $this->route('post'));
    }

    public function rules(): array
    {
        return [
            // バリデーションルール...
        ];
    }
}

2. 絶対パスと相対パスのルート生成

route() ヘルパーはデフォルトで 絶対パス を生成しますが、第3引数に false を渡すと 相対パス を生成できます。

<?php

route('tips', $tip->id); // https://example.com/tips/1
route('tips', $tip->id, false); // /tips/1

3. ルートモデルバインディングでカスタム動作を設定

missing() メソッドを使うと、ルートモデルバインディングでモデルが見つからなかった場合の動作をカスタマイズできます。

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;

Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
    ->name('locations.view')
    ->missing(function (Request $request) {
        return Redirect::route('locations.index');
    });

4. ルートモデルバインディングのカスタム解決

デフォルトでは ID でモデルを解決しますが、resolveRouteBinding メソッドをオーバーライドすると、
sluguuid などを使ってモデルを解決できます。

<?php

class Post extends Model
{
    public function resolveRouteBinding($value, $field = null)
    {
        return $this->where('slug', $value)
            ->orWhere('uuid', $value)
            ->firstOrFail();
    }
}

// /post/{slug} も /post/{uuid} も動作する
Route::get('/post/{post}', fn (Post $post) => $post);

5. 複数のリソースコントローラをグループ化

複数のリソースコントローラを一括で登録できる resources() を使うと、ルート定義がスッキリします。

<?php

use App\Http\Controllers\PostsController;
use App\Http\Controllers\PhotosController;

// 従来の書き方
Route::resource('posts', PostsController::class);
Route::resource('photos', PhotosController::class);

// スマートな書き方
Route::resources([
    'posts' => PostsController::class,
    'photos' => PhotosController::class,
]);

6. ソフトデリート済みのモデルをバインド

withTrashed() を使うと、削除済みのモデルも含めてルートモデルバインディングできます。

<?php

use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    return $user->email;
})->withTrashed();

7. URL フラグメントを追加してリダイレクト

withFragment() を使うと、リダイレクト先の URL に #testimonials などの フラグメント(アンカー) を追加できます。

<?php

return redirect()->back()->withFragment('testimonials'); // example.com/#testimonials

return redirect()->route('product.show')->withFragment('reviews'); // example.com/product/1#reviews

8. 外部サイトへリダイレクト

redirect()->away() を使うと、外部サイトへリダイレクトできます。

<?php

redirect()->away('https://blog.example.com');

9. ルート定義を短縮する view ルート

シンプルなビューを表示するルートを定義する場合、Route::view() を使うとコードを短縮できます。

<?php

use Illuminate\Support\Facades\Route;

// 通常の書き方
Route::get('/welcome', function () {
    return view('welcome', ['foo' => 'bar']);
});

// シンプルな書き方
Route::view('/welcome', 'welcome', ['foo' => 'bar']);

10. Singleton ルートの定義

特定のリソース(例:プロフィール)が単一のインスタンスのみを持つ場合、Route::singleton() を使うと便利です。

<?php

use App\Http\Controllers\ProfileController;

Route::singleton('profile', ProfileController::class);

/*
生成されるルート:
GET         /profile
GET         /profile/edit
PUT/PATCH   /profile
*/

11. キャッシュヘッダーを動的に設定

SetCacheHeaders ミドルウェアを利用すると、キャッシュ設定をルートごとに適用できます。

<?php

Route::middleware('cache.headers:public;max_age=2628000;etag')->group(function () {
    Route::get('/privacy', function () {
        // ...
    });

    Route::get('/terms', function () {
        // ...
    });
});

12. to_route() で簡単リダイレクト

redirect()->route() の代わりに to_route() を使うと、可読性が向上します。

<?php

// 通常の書き方
return redirect()->route('profile');

// 簡潔な書き方
return to_route('profile');

13. 特定のルートでミドルウェアを除外

withoutMiddleware() を使うと、特定のルートだけミドルウェアを除外できます。

<?php

use App\Http\Middleware\EnsureTokenIsValid;

Route::middleware([EnsureTokenIsValid::class])->group(function () {
    Route::get('/', function () {
        // ...
    });

    Route::get('/profile', function () {
        // ...
    })->withoutMiddleware([EnsureTokenIsValid::class]); // ここではミドルウェアを適用しない
});

14. カスタムリダイレクト先を設定

フォームリクエストでバリデーションエラー時のリダイレクト先を指定できます。

<?php

// URL へのリダイレクト
protected $redirect = '/dashboard';

// 名前付きルート
protected $redirectRoute = 'dashboard';

// コントローラのアクション
protected $redirectAction = [DashboardController::class, 'index'];

15. 署名付きルート(Signed Routes)

URL に署名を付与して、安全な一時的なリンクを生成できます。

<?php

use Illuminate\Support\Facades\URL;

// 署名付きルートの生成(絶対URL)
URL::signedRoute('unsubscribe', ['user' => 1]);

// 相対URL
URL::signedRoute('unsubscribe', ['user' => 1], absolute: false);

// 30分間有効な一時的な署名付きルート
URL::temporarySignedRoute('unsubscribe', now()->addMinutes(30), ['user' => 1], absolute: false);

元記事

https://github.com/OussamaMater/Laravel-Tips/blob/main/tips/routing.md?plain=1

Discussion