Laravel Tips集 ~Routing & Request の便利技大全~
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
メソッドをオーバーライドすると、
slug
や uuid
などを使ってモデルを解決できます。
<?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 () {
// ...
});
});
to_route()
で簡単リダイレクト
12. 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);
元記事
Discussion