結論
任意のRequestクラスに以下の関数を追加する。
/**
* 更新、削除時に渡されるルート引数を Request Parametersに含める。
* ただし、すでにキーが存在している場合は上書きしない。
* @return array
*/
public function validationData()
{
$params = $this->all();
$route_params = $this->route()->parameters();
return $params + $route_params;
}
なんで作ろうと思ったか?
APIを作っていて、更新処理を書いている時にふと思った。
public function update(ProjectUpdateRequest $request, $id)
{
$project = Project::find($id);
// もしデータが取得できなかったら 失敗のレスポンス
if (empty($project)) return response()->json(['result' => 'failed']);
$project->fill($request->all());
$project->update();
return response()->json($project);
}
せっかくバリデーション専用のクラスあるのに、ここでパラメータをチェックするの違和感ある。
どうにかしてRequestクラスでできないだろうか。
Requestクラス内でルートパラメータ取得
紆余曲折あったが、パラメータを取得する関数を発見したのでそれを使用。
$this->route()->parameters()
/project/{id} だったら ['id' => xxx]の形で取得できる。
Rulesでバリデーションできるようにする
Requestクラスの rules()でチェックされるデータは validationData()で取得しているので、オーバーライドしてルートパラメーターを含めるようにする。
ただし、ルートパラメータと同じ値があったときに上書きするのは望ましくないので、array_mergeは使わずに配列をマージすることにした。
$params = $this->all();
$route_params = $this->route()->parameters();
return $params + $route_params;
結果
rules()で、ルートパラメータを使ってバリデーションを行えた。
とっても満足した。
効率や生産性、拡張性は見なかったことにする。