laravel5.5の新規作成のバリデーションで、別の会社なら同じログインIDがあってもOKにする方法(複数カラムのUNIQUE制約について)
1, userテーブルにて、usernameのunique制約を外して、会社IDとログインIDの組み合わせでunique制約になるように変更しておく事
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('username')->comment('email代わりのログインID'); $table->string('email'); $table->string('password'); $table->integer('company_id')->unsigned()->comment('どの会社のアカウントか?'); $table->rememberToken(); $table->timestamps(); $table->softDeletes()->comment('ソフトデリートのためのdeleted_atカラム追加'); // 別の会社なら、同じログインIDがあってもOK! $table->unique(['username', 'company_id']); //文字列の外部キー参照元は主キーorユニーク。主キーの場合は、こちらのカラムが符号なしにする事!->unsigned() $table->foreign('company_id')->references('id')->on('companies'); }); // スキーマビルダーではテーブル自体のコメントは出来ない?のでSQL文で実行 DB::statement("ALTER TABLE ".DB::getTablePrefix()."users COMMENT '企業担当者'"); } |
2, 新規作成バリデーション・ルール
1 2 3 4 5 6 7 8 9 10 |
$company_id = 1; $this->validate($request, [ 'username' => ['required', 'string', 'max:255', // 別の会社なら、同じログインIDがあってもOK! 'unique:users,username,NULL,id, company_id,'. $company_id ], ]); $data = $request->all(); |
uniqueの引数
第1引数 テーブル名
第2引数 uniqueにしたいカラム名
第3引数 unique制約の除外対象レコードのキー値(単純なupdateなら更新レコードのid, 今回はusernameを重複OKにするので除外無し=NULL)
第4引数 第3引数の除外レコードを決めるための対象カラム名(指定しなければidカラム、第三引数がNULLなら何でもOK)
// UNIQUE制約をする前に、where句で絞り込む処理を行う
第5引数 unique制約処理をする前のwhere句のカラム名(company_id)
第6引数 unique制約処理をする前のwhere句の値(変数となる)
※カンマの前後に半角スペース・改行があるとカラム名が認識されなくなるから、ダメ!
ややこしいけど、要約すると、こんな感じ(名前空間と同じ発想)
1, 全レコードで、usernameは重なってもOK(第1~4引数)
2, ただし、同じ会社内でusernameは重なってたらNG(第5~6引数)
例)
company_id, username
1, adam
2, bell
3, cecil
// これは、バリデーションOK
insert into users(company_id, username)values(1, ‘bell’);
1, adam
1, bell ←←← NEW!
2, bell ←←← 第5~6引数の効果により、見えない状態でINSERT
3, cecil ←←← 第5~6引数の効果により、見えない状態でINSERT
// これも、バリデーションOK
insert into users(company_id, username)values(1, ‘cecil’);
1, adam
1, bell
1, cecil ←←← NEW!
2, bell ←←← 第5~6引数の効果により、見えない状態でINSERT
3, cecil ←←← 第5~6引数の効果により、見えない状態でINSERT
// これは、バリデーションNG!!!
// 第2引数のusernameに引っかかる
insert into users(company_id, username)values(1, ‘adam’);
1, adam
1, bell
1, cecil
2, bell ←←← 第5~6引数の効果により、見えない状態でINSERT
3, cecil ←←← 第5~6引数の効果により、見えない状態でINSERT
更新のバリデーション・ルールは、どうすればいいんだろ?
まあ、username(ログインID)は更新不可でも、システム的に問題は無いか。