Help us understand the problem. What is going on with this article?

LaravelのFormRequestでControllerをスマートに書いてみよう。

LaravelのFormRequestでControllerをスマートに書いてみよう。

by sivchari
1 / 2

概要

Laravel:FormRequestの実装方法とメリット

前提

Laravelを初めて触る人、他のフレームワークを触ってMVCでの書き方が理解できていることを前提にお話を進めていきます。

また、Laravelというフレームワークに初めて触ったであろう人を前提に書くのですでに知識がある方には物足りない可能性がございます。

ご了承ください。

FormRequestって何?

プログラミングでバリデーションをすることは、開発をする上で必須の知識であることは何か1つでも開発したことあれば理解できるでしょう。

しかし、このバリデーションは同じ言語だとしてもフレームワークによって当然変化していきます。
例えば同じPHPのフレームワークであるCakePHPを例に挙げるとモデル内に記述していきます。

Hoge.php
class Hoge extends AppModel {
    public $validate = array(
        'login' => 'alphaNumeric',
        'email' => 'email',
        'born'  => 'date'
    );
}

CakePHP 2.x Cookbook データバリデーション
このような記述ですね。

これがLaravelだとどうなるのでしょうか?
参考書などで紹介されているバリデーションは、Controller内で行っているものが多いですね。
例えばこのような感じです。

HogeController.php
public function fuga(Request $request)
{
    $validatedData = $request->validate([
        'title' => 'required',
        'body' => 'required',
    ],[
        'title.required' => 'タイトルは必須です。',
        'body.required'  => 'bodyは必須項目です。',
    ]);

}

Laravel 5.5 バリデーション

これが参考書などによく掲載されているパターンで
use Illuminate\Http\Request;
によってRequestクラスが外部注入(別の場所で用意されている武器を身につけるイメージです)されhoge.blade.phpから送られてきたformの値などをバリデーションしています。

豆知識

public function fuga(Request $request)

この部分は外部で記述されたインスタンス(Requestという物の素のイメージ)を$requestという引数に割り当てることでコントローラーの中でのnewを使ったインスタンスの作成を無くしています。

HogeController.php
public function fuga(Request $request)
{
    /*引数に宣言することで
    $request = new Reqeust();
    これを書く必要が無くなります!!*/
}

ここまでだと「この書き方でも問題ないんじゃない?」と思う方もいるかもしれません。
しかし、仮にサービスを開発していく中でバリデーションしなければいけないformが100個(現実的ではありませんがわかりやすく)あった場合どうなるでしょう?

気づいている方もいるかと思いますがバリデーションの項目を記述するだけでメソッド1つだけで100行以上になることになりますよね。メッセージも全部設定したら300行も余裕ですね(笑)
処理としては問題ないけど、、、という感じです。

ではどうしていくべきなのか。ここでFormRequestの登場です。

コマンドで作成

   php artisan make:request XXXXRequest

XXXX の部分は任意で好きな名前にしてください。
このコマンドで作成されたXXXXRequestは app/Http/Requests の配下に作成されます。
開いてみると

app/Http/Requests/XXXXRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class XXXXRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }
}
public function authorize()
    {
        //return false; アクセスに制限をかけない場合はtrueに変更でしましょう
          return true;
    }

次にバリデーションのルールを書いていきます。
場所は

    public function rules()
    {
        return [
            'title' => 'required',
            'body' => 'required',
        ];
    }
}

先ほどのバリデーションをこのように定義づけてあげるだけOKです!
同じくエラーメッセージもmessagesメソッドを増やしてあげて

    public function messages(){
        return [
            'title.required' => 'タイトルは必須です。',
            'body.required'  => 'bodyは必須項目です。',
        ];
    }

}

これで完璧です👍

全体としてみて挙げるとこんな感じです。

app/Http/Requests/XXXXRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class XXXXRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required',
            'body' => 'required',
        ];
    }

    public function messages(){
        return [
            'title.required' => 'タイトルは必須です。',
            'body.required'  => 'bodyは必須項目です。',
        ];
    }
}

いい感じですね。これだけでバリデーションをコントローラーから分離させることに成功しました。

FormRequestを実装したことによって生じるメリットは以下の通りになります。

  • 同じ内容でバリデーションを行いたいときに使い回しが可能。

  • コントローラーでのバリデーションがなくなるため可読性が高まる。

  • 独自のバリデーションを作成するなどの工夫がしやすい。

  • メソッドの前にFormRequestを通過するため毎回エラー時にメソッドを通らなくてよくなる。

作成したFormRequestの使用方法

早速作成したFormRequestを使用していきましょう。使用方法は簡単です。
先ほどのメソッドのRequest部分を作成したXXXXRequestに名前を変更します。

HogeController.php
    use App\Http\Requests\XXXXRequest; //忘れないように注意!!


    public function fuga(XXXXRequest $request) {
        // バリデーション通過後の処理
    }

余裕ですね😎

まとめ

FormRequestは一度知れば簡単な基礎でありながらも開発時の可読性など大事な部分に直結する技術です。

この記事を読めば誰でも実装出来るよう書いたつもりですが、ご指摘ありましたらよろしくお願い致します。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした