こんにちは、最近ロードバイクにはまっているぱふゅーむです。
現在チームでは、ロードバイクがブームでこの半年で4人が購入しています。
ただの置物にしちゃっているメンバーが1名いますが笑(たまに座って満足しているそうです、怖いですね。。)
ということで今回はロードバイクのすすめ・・・ではなく LaravelのMiddlewareを使ったちょっとしたテクニックを紹介したいと思います。
Middlewareについて
Middlewareの詳細な説明は今回は割愛します。
詳細を確認したい方はこちらをご覧ください。=> Laravel - ウェブ職人のためのPHPフレームワーク Middleware
ルートパラメータチェックをMiddlewareで行い、ついでに取得した値をリクエストに内包する
ルートパラメータで取得したidが存在するかMiddlewareでチェックしたいケースなどに使えるテクニックです。
Middleware内でfind()したモデルをリクエストに内包することで、
Controllerに渡した後、再度取得する処理を省略することができます。
以下のようなルーティングを設定していたとします。
Route::get('/{hogeId}', 'HogeController@detail')->middleware('ValidatePkMiddleware') Route::get('/{fugaId}', 'FugaController@detail')->middleware('ValidatePkMiddleware')
Middleware内でidの存在をチェックしたいModelを、配列で定義します。
<php class ValidatePkMiddleware { /** * routeで指定したidの存在を確認し、検索結果をrequestに含める(Controllerで使用可能にする) * Controller での参照は xxxId の場合は 「$request->xxx」(Idを取り除いた形式) となる * ※ 存在確認が主目的なので、結合などは考慮しない * * @var array [ routeで指定したKey => 対象Model ] */ private static $validateList = [ 'hogeId' => Hoge::class, 'fugaId' => Fuga::class, ];
上記で定義した配列を使用し、以下のようにルートパラメーターを取得、存在をチェックします。
この例では存在しなかった場合404を投げるようにしています。
存在チェックにexists()を使用せず、find()しているところがミソです。
存在した場合、リクエストに内包し、Controller以下の処理で値を参照できるようにしています。
このようにすることで、各処理でfind()を省略することができます。
/** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { foreach (self::$validateList as $routeKey => $modelClass) { $key = $request->route($routeKey); if ($key === null) { continue; } $model = (new $modelClass())->find((int) $key); if ($model === null) { abort(404, trans('messages.not_found')); } $requestKey = str_replace('Id', '', $routeKey); $request->merge([ 'fromDb' => (object) [$requestKey => $model], ]); } return $next($request); } }
単純ですが、こういったちょっとした工夫の積み重ねで、後の実装が楽になりますよね!
\\『明日のはたらくを創る』仲間を募集中です!! //
919.jp