9
9

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 5 years have passed since last update.

Advent Calendar 2018

Day 1

Laravel のバリデーションルール exists に Eloquent を使う

Last updated at Posted at 2018-11-30

千株式会社の初 Advent Calendar、私の初 Qiita !

追記:強化版ができました
Laravel のバリデーションルール exists に Eloquent を使う v2

背景

Laravel の DB レコード存在チェックをするバリデーションルールとして exists がある

しかしハードコーディングな要素が多いので、Eloquent を使って要素を意識させないようにしたい

例えば、ソフトデリートを考慮するには、

  • テーブル名
  • 検索するカラム名
  • ソフトデリートのカラム名
  • ソフトデリートの削除されていないときの値

を知って、コントローラかフォームリクエストに書く

'id' => [
    'required',
    'integer',
    'exists:hoges,id,deleted_at,null', // これ
],

Eloquent を使っていると、グローバルスコープでカラム名やその値を意識せずに書けるので、バリデーションもそうしたい

解決策

カスタムバリデーションルールのなかでは、ルールオブジェクトがシンプルに書けるので使う

ルールオブジェクトのクラスのソースコードが次
コンストラクタが使われていないので、そこでモデルクラスを渡す

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Exists implements Rule
{
    protected $modelName;
    protected $propertyName;

    public function __construct(string $modelName, ?string $propertyName = null)
    {
        $this->modelName = $modelName;
        $this->propertyName = $propertyName;
    }

    public function passes($attribute, $value)
    {
        if ($this->propertyName === null) {
            $this->propertyName = $attribute;
        }

        return $this->modelName::where($this->propertyName, $value)->exists();
    }

    public function message()
    {
        return ':attribute はデータが存在しません';
    }
}

使い方

リクエストのフィールド名と同じカラム名で探すなら

use App\Hoge;
use App\Rules\Exists;
'id' => [
    'required',
    'integer',
    new Exists(Hoge::class), // これ
],

と書けば、ソフトデリートなどのグローバルスコープも考慮してくれる

リクエストのフィールド名と異なるなら、カラム名を指定できる

'hoge_id' => [
    'required',
    'integer',
    new Exists(Hoge::class, 'id'), // これ
],

すっきり!

追伸

使ってみるとカラム名を指定することが多い&主キーで探すことが多いので、指定がないときはフィールド名と同じではなく主キーのほうがより良さそう

あとで変えるかも

9
9
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
9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?