0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

フォームリクエストとバリデーション - Laravel学習 #4

0
Posted at

フォームリクエスト

以下のようにフォームリクエストを作成し、コントローラーから処理を分離できる。

php artisan make:request HogeRequest
  • StoreXXXXRequestとすることが多いっぽい
App\Http\Request\HogeRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreContactRequest extends FormRequest
{
    public function authorize()
    {
        return false;
    }

    public function rules()
    {
        return [
            //
        ];
    }
}

  • 簡単に認可・バリデーションを行うことが可能
  • コントローラーからバリデーションを切り離せる
    • テストしやすい
    • Fat Controllerを避けられる

authrize()

  • バリデーションを受ける前に実行されるもの
  • falseの場合は403 Forbiddenを返し、アクセスを拒否する
  • 初期状態はfalseなのでtrueに書き換える
    public function authorize()
    {
        return true;
    }

許可の例

  • ロールがadminのユーザーのみ許可することもできる
    public function authorize()
    {
        return auth()->user()->role === 'admin';
    }
  • カスタム権限システムやパーミッションベースのシステムを使用して、ユーザーに特定の許可がある場合のみリクエストを許可もできる
    以下は編集権限を持っているユーザーのみ許可している
    public function authorize()
    {
        return auth()->user()->hasPermission('edit-posts');
    }
  • 自分のプロフィールを編集する際など、特定のリソースの所有者だけがリクエストを許可
    public function authorize()
    {
        $profile = Profile::find($this->route('profile_id'));
        return auth()->user()->id === $profile->user_id;
    }
  • このほかにも時間やIPアドレス、年齢などに基づいて許可するなどができる

バリデーション

バリデーションの基礎

  • バリデーションロジック
  • Illuminate\Http\Requestオブジェクトが提供するvalidateメソッドを使用
    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
          // key   => value(条件)
        ]);

        // 配列のような書き方もできる
        $validatedData = $request->validate([
            'title' => ['required', 'unique:posts', 'max:255'],
            'body' => ['required'],
        ]);
        
        return redirect('/posts');
    }
  • ビューでエラーを表示する
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

フォームリクエストバリデーション

  • フォームリクエストのrulesにバリデーションを書く
php:App\Http\Request\HogeRequest.php
public function rules(): array
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

使用可能なバリデーションルール

  • 必須かどうか、日付やメールアドレスかどうかなどさまざまなバリデーションが用意されている
  • よく使うもの
    • required:必須
    • string:文字列であるか
    • max:20:最大長
    • email:メールアドレスか
    • nullable:nullであることを許容する
    • boolean:true、false、1、0、"1"、"0"のいずれかか
    • accepted:利用規約などに使う。"yes"、"on"、1、"1"、true、"true"かどうか

コントローラーのstoreでバリデーションを使用する

App/Http/Controllers/HogeController.php
use App\Http\Requests\HogeRequest;

    // public function store(Request $request)
    //                        ↓↓↓↓
    public function store(HogeRequest $request)
    {
        
    }
  • おさらい:storeはフォームで送られてきた内容を、データベースに新規保存している

ビューでエラーを表示する

  • パーツを作って呼び出すのがよい
/resources/views/components/input-error.blade.php
@props(['messages'])

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
// 一箇所に全てのエラーを表示
<x-input-error :messages="$errors->all()" />
// どのエラーを出すか選ぶこともできる
<x-input-error :messages="$errors->get('email')" />

その他参考

バリデーションの方法3つ

  • Illuminate\Http\Requestのvalidateメソッド
  • Validatorファサード
  • FormRequest(フォームリクエスト)

よく使うバリデーションや書き方の例

  • よく使うバリデーションルール
  • 独自でバリデーションルールを作れる
  • エラーメッセージのカスタマイズ
    • 多言語
    • カスタムメッセージ
  • エラーメッセージの動的な切り替え
use Illuminate\Support\Facades\Validator;

$validator = Validator::make($request->all(), [
        'age' => 'required|integer|min:18',
    ], [
        'age.min' => function ($message, $attribute, $rule, $parameters) {
            $minimumAge = $parameters[0];
            return "申し訳ありませんが、{$minimumAge}歳未満の方は登録できません。";
        }
    ]);
public function messages()
{
    $messages = [
        'title.required' => ':attributeは必須です。',
        'content.min' => ':attributeは最低:min文字必要です。',
    ];
    // ユーザーの役割に基づいてメッセージを変更
    if (auth()->user()->isAdmin()) {
        $messages['title.required'] = '管理者は必ずタイトルを入力してください。';
    }
    return $messages;
}

など

  • テスト可能なバリデーションや、ファイルアップロード時のバリデーションの書き方なども記載されている
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?