18
15

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.

[Laravel]バリデーションのuniqueにおける条件指定について

Last updated at Posted at 2016-02-26

#先に結論

  • uniqueルールの追加条件の指定はイコール以外も色々行ける。
  • NULL, NOT_NULLを指定する場合は大文字でなくてはいけない。
  • 小文字だと文字列として比較する。
unique:table,column,except,idColumn以降 付加される条件
,column,!value (Larvel5.2以降) column != value
,column,NULL column is null
,column,NOT_NULL column is not null

※,column,!valueが指定できるのは5.2以降でした。
※また、column1,value1,column2,value2,...と続ければ複数個設定できる。
※フィールドの値が、指定されたデータベーステーブルに存在することをバリデートするexistsルールも同様。

#以下雑記

Laravelのバリデーションにはuniqueという、指定したフィールドがテーブル内で一意であることをチェックする為のルールがあります。
http://readouble.com/laravel/5/1/ja/validation.html#rule-unique

ユーザ登録周りの処理なんか書くときなんかすごい便利そうですね。

でもこれ、Eloquentモデルのほうでソフトデリート設定してたとしても、親切にデリートされたレコードを無視してくれるなんてことは無いみたいでチェック時に発行されるクエリは以下のようになります

select count(*) as affregate from `users` where `email_address` = 'test@example.com'

当然既に削除されているemail_addressがtest@example.comのレコードがあれば、uniqueルールは通りません。

うわー使えねー。と思うにはまだ早いです。uniqueルールには追加のWHERE節を付け加える事ができます。
ということでdleted_at,nullとか設定すると発行されるのは

select count(*) as affregate from `users` where `email_address` = 'test@example.com' and `deleted_at` = 'null'

。。。違う。

ダメかーカスタムバリデーション作らなきゃダメかーと思いましたが、Laravelのソースコードは読みやすいと評判なのでダメ元で読んでみると

Illuminate\Validation\ValidatorのvalidateUniqueメソッドが呼ばれていて、追加条件の設定を追っていくと
Illuminate\Validation\DatabasePresenceVerifierのaddWhereメソッドにたどり着きました。

そこに書かれていたものが、こちら

    protected function addWhere($query, $key, $extraValue)
    {
        if ($extraValue === 'NULL') {
            $query->whereNull($key);
        } elseif ($extraValue === 'NOT_NULL') {
            $query->whereNotNull($key);
        } elseif (Str::startsWith($extraValue, '!')) {
            $query->where($key, '!=', mb_substr($extraValue, 1));
        } else {
            $query->where($key, $extraValue);
        }
    }

。。。解決!!

その後見ていたらExistsルールのところに全部書いてあるじゃないですか。
http://readouble.com/laravel/5/1/ja/validation.html#rule-exists
uniqueでも一緒とは書いてないけど。
まぁ結論はドキュメントちゃんと読めということですかね。

文字列としてNULL、NOT_NULLを条件にしたい時はどうしたらいいんだ。
まぁそんなケース無いだろうけど。

18
15
2

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
18
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?