「重複回避-DB重複エラーを利用」で使用した以下のコントローラのメソッドをここでもう一度掲載します。
public function postSignup(Request $request)
{
$rules = [
'email' => 'required|email|unique:member,email',
'password' => 'required|min:6|max:20|confirmed',
'first_name' => 'required',
'last_name' => 'required'
];
$messages = [
'email.unique' => "Eメールアドレスはすでに使用されています"
];
$this->validate($request, $rules, $messages);
try
{
$member = Member::create($request->all());
}
catch(IlluminateDatabaseQueryException $e)
{
$errorCode = $e->errorInfo[1];
if($errorCode == 1062) //重複エラーをここでキャッチ
{
return back()->withInput()->withErrors(['email' => "Eメールアドレスはすでに使用されています"]);
}
}
return "登録完了";
}
フォームでの入力により送信された値は、このメソッドのパラメータ変数$requestに収められます。それらをバリデーションして、エラーがあれば表示、なければ新規の会員のDBレコードを作成。さらに、タイミングエラーにより逃れた重複エラーも発生するならキャッチ。まとまってとてもわかりやすいです。これはこれで十分と思います。
しかし、このコントローラのコードがより複雑になったときに、たとえば、新規会員、編集、パスワードの編集と会員関連のバリデーションを一箇所に集めて管理性を高めたいときはどうしましょう?
もちろん、1つのコントローラでpostSignup()のようにそれぞれのメソッドで対応するのも1つのやり方、しかし、会員のすべての処理を1つのコントローラで対応することはできません。例えば、ユーザーはエンドユーザーだけでなく管理者も会員処理が必要となります。その場合は少なくともユーザーと管理者に別々のコントローラを持つことになるでしょう。そうなら、モデルのMember.phpに入れるのも1つの手です。
ここでは、それらとまったく違う手法、フォームリクエストを紹介します。ララベル5.1以降が必要です。
フォームリクエストは、まずapp/Http/Requests/MemberRequest.phpのファイルを作成して、以下のように先のコントローラのバリデーション部分を移行します。
namespace AppHttpRequests;
use AppHttpRequestsRequest;
class MemberRequest extends Request {
public function authorize()
{
return true;
}
public function rules()
{
return [
'email' => 'required|email|unique:member,email',
'password' => 'required|min:6|max:20|confirmed',
'first_name' => 'required',
'last_name' => 'required'
];
}
}
これにより先のコントローラは以下のようにシンプルになります。
public function postSignup(MemberRequest $request)
{
try
{
$member = Member::create($request->all());
}
catch(IlluminateDatabaseQueryException $e)
{
$errorCode = $e->errorInfo[1];
if($errorCode == 1062) //重複エラーをここでキャッチ
{
return back()->withInput()->withErrors(['email' => "Eメールアドレスはすでに使用されています"]);
}
}
return "登録完了";
}
パラメータにおいて、$requestのタイプが、RequestからMemberRequestに変わったことに注意してください。
さて、validateの関数のコールはどこへ行ったのでしょうね?
validateの関数のコールは、MemberRequestのオブジェクトが生成されるとともに、その中で実行されます。そしてエラーがあれば画面にエラーを表示し、エラーがなければ、postSignup()の残りのコードを処理します。
今回はシンプルな例でしたが、将来はより複雑な例を紹介しましょう。
メルマガ購読の申し込みはこちらから。