3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel 6.x 1つのフォームリクエストで、複数のバリデーションの分岐を考えてみた件

Last updated at Posted at 2020-10-14

#制作環境

Windows 10
Laravel : 6.18.35
Laravel/ui : 1.0
Laravel-mix : 5.0.1
Bootstrap : 4.0.0
MDBootstrap : 4.19.1
chart.js : 2.9.3
XAMPP
PHP : 7.4.3
Visual Studio Code

#はじめに
この記事はプログラミングをはじめたばかりの素人が、できたことをメモするのに利用しています。
内容には誤りがあるかもしれません。

#やりたい事
1ページの中に複数のフォームがあるような場合に、postされた項目に応じて、必要なバリデーションルールを抽出してreturnするようにする。

#制作理由
1ページの中に複数のフォームがあるような場合に、フォーム数に応じてバリデーションルールを作るのが大変だと思い、1つのフォームリクエストで条件分岐できる方法を素人なりに考えてみました。
条件の組み合わせも簡単にできるので、どうでしょうかね?

#注意
素人が考えたことなので、もっといい方法があるかもしれません。
良くも悪くも参考にしてください。

テスト的に作ったものなので、デザイン等は完全無視です。
思った結果になるかどうかだけ重視してます。

#はじめる前に
Laravelが既にインストールされている前提で書いてます。
インストールされてない場合は、インストールして下さいね。

#コントローラーの作成
プロジェクトのディレクトリでターミナルを起動し、以下を実行して下さい。

php artisan make:controller TestController

できたら、内容を以下のように記述します。

TestController.php
use App\Http\Requests\TestRequest;

class TestController extends Controller
{
    public function index()
    {
        return view('test', ['msg' => 'フォーム1を入力', 'msg2' => 'フォーム2を入力']);
    }

    public function post(TestRequest $request)
    {
        return view('test', ['msg' => '正しく入力されました。', 'msg2' => 'フォーム2を入力']);
    }

    public function put(TestRequest $request)
    {
        return view('test', ['msg' => 'フォーム1を入力', 'msg2' => '正しく入力されました。']);
    }
}

フォームリクエストのTestRequestは後で作成します。

#ビューの作成
resources>views の中に新しくtest.blade.phpを作成します。

test.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>テスト</title>
</head>
<body>
  <h1>テスト</h1>

  <p>{{ $msg }}</p>

@error('name')
<p>{{ $message }}</p>
@enderror

@error('email')
<p>{{ $message }}</p>
@enderror

  <form action="/test" method="post">
  @csrf
    <label>名前: <input type="text" name="name"></label>
    <label>メルアド: <input type="email" name="email"></label>
    <input type="submit" value="送信">
  </form>

<p>{{ $msg2 }}</p>

@error('tel')
<p>{{ $message }}</p>
@enderror

<form action="/test" method="post">
  @method('put')
  @csrf
    <label>携帯電話: <input type="tel" name="tel"></label>
    <input type="submit" value="送信">
  </form>
</body>
</html>

こんな感じです↓
testform.jpg

####仕様
フォーム1とフォーム2の2つを用意しています。
本当はフォーム1に商品登録フォーム、フォーム2に登録した商品情報の変更(在庫数等)をやりたい所ですが、実験なので簡易的な内容でいきます。

フォーム1のメソッドはPOSTです。
なので、ルーティングはRoute::postを使います。

フォーム2のメソッドはPOSTですが、ルーティングを変更する為、@method('put')でPUTにしてます。
なので、ルーティングはRoute::putを使います。

#フォームリクエストの作成
ターミナルを起動し、以下を実行して下さい。

php artisan make:request TestRequest

app>Http>Requests 内に作成されたTestRequest.phpを開き、以下のように編集してください。

TestRequest.php
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    // 今回認証はしません。
    public function authorize()
    {
        return true;  // trueに変更
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        // バリデーションルールをまとめる配列です。
        $rules = [];
 
        // $this->has()は$request->has()のことです。
        // has()で指定した項目の有無を確認し、あればルールを追加します。    
        if ($this->has('name')) {
            $rules['name'] = 'required';
        }

        if ($this->has('email')) {
            $rules['email'] = 'email';
        }

        if ($this->has('tel')) {
            $rules['tel'] = 'required|regex:/^[0][0-9][0]-[0-9]+-[0-9]+$/';
        }

        return $rules;
    }

    // バリデーションでエラーが発生した場合のエラーメッセージです。
    public function messages()
    {
        return [
            'name.required' => '名前は必須です。',
            'email.email'   => 'メールアドレスを入力して下さい。',
            'tel.required'  => '携帯の番号は必須です。',
            'tel.regex'     => '携帯の番号を入力してください。',
        ];
    }

####仕様
この部分で必要なバリデーションルールの抽出を行ってます。
下記では、POSTで送信される項目の中に「name」があれば、ルールを追加し、なければ追加はしません。

TestRequest.php
if ($this->has('name')) {
    $rules['name'] = 'required';
}

ここで抽出した値を返してます。

TestRequest.php
return $rules;

上記は、フォーム1の内容であれば下記の内容が返ります。

TestRequest.php
return [
  'name'  => 'required',
  'email' => 'email',
];

バリデーションルールは実験なので簡単な内容にしてあります。
nameは必須項目、メールはメールの値かのチェックだけです。
telは携帯番号にしてありますが、正規表現で0x0-xxxx-xxxxの番号しかパスしないようにしてます。

正規表現作成サイト
https://rubular.com/

#ルーティングの編集
routes 内のweb.phpを開き、以下のように編集します。

web.php
Route::get('/test', 'TestController@index');
Route::post('/test', 'TestController@post');
Route::put('/test', 'TestController@put');

これで完成です。

#実際の動作
####フォーム1を空で送信
フォーム1のエラーメッセージのみ表示されます。

form1.jpg

####フォーム1の名前だけ入力して送信
今度はメルアドだけのエラーメッセージが表示されます。

mail.jpg

####フォーム2を空で送信
フォーム2のエラーメッセージのみ表示されます。

form2.jpg

####フォーム1を正しく入力した場合
「正しく入力されました。」と表示されます。

formcom.jpg

####フォーム2を正しく入力した場合
「正しく入力されました。」と表示されます。

form2com.jpg

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?