質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Vagrant

Vagrantは、VirtualBox上の仮想マシンを コマンドラインから作成してくれるソフトウェアです。 ビルド環境など容易に構築が可能です。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

2回答

6446閲覧

Laravel5.5でのFormRequestを使った複合ユニークでの重複チェック

sabamiso

総合スコア14

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Vagrant

Vagrantは、VirtualBox上の仮想マシンを コマンドラインから作成してくれるソフトウェアです。 ビルド環境など容易に構築が可能です。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

0クリップ

投稿2018/05/20 09:00

編集2018/05/21 04:06

実現したいこと

前提
タスクリストモデルとタスクモデルが存在し、タスクリスト(1)がタスク(多)のリレーションを設定している。

データ構造

sql

1mysql> show columns from task_lists; 2+------------+------------------+------+-----+---------+----------------+ 3| Field | Type | Null | Key | Default | Extra | 4+------------+------------------+------+-----+---------+----------------+ 5| id | int(10) unsigned | NO | PRI | NULL | auto_increment | 6| list_name | varchar(191) | NO | | NULL | | 7| created_at | timestamp | YES | | NULL | | 8| updated_at | timestamp | YES | | NULL | | 9+------------+------------------+------+-----+---------+----------------+

sql

1mysql> show columns from tasks; 2+--------------+------------------+------+-----+---------+----------------+ 3| Field | Type | Null | Key | Default | Extra | 4+--------------+------------------+------+-----+---------+----------------+ 5| id | int(10) unsigned | NO | PRI | NULL | auto_increment | 6| task_list_id | int(10) unsigned | NO | MUL | NULL | | 7| task_name | varchar(191) | NO | | NULL | | 8| limit | date | NO | | NULL | | 9| done | tinyint(1) | NO | | 0 | | 10| created_at | timestamp | YES | | NULL | | 11| updated_at | timestamp | YES | | NULL | | 12+--------------+------------------+------+-----+---------+----------------+

モデル

php

1<?php 2 3namespace App; 4 5use Illuminate\Database\Eloquent\Model; 6 7class TaskList extends Model 8{ 9 protected $fillable = ['list_name']; 10 11 public function tasks(){ 12 return $this->hasMany('App\Task'); 13 } 14} 15

php

1<?php 2 3namespace App; 4 5use Illuminate\Database\Eloquent\Model; 6 7class Task extends Model 8{ 9 protected $fillable = ['task_name', 'limit']; 10 11 public function tasklist(){ 12 return $this->belongsTo('App/TaskList'); 13 } 14}

viewのタスク追加フォーム

php

1 <form method="post" action="{{ action('TaskController@store', $list) }}" > 2 {{ csrf_field() }} 3 <div class="form-group"> 4 <label for="nameInput">タスク名</label> 5 <input type="text" class="form-control" id="nameInput" name="task_name"> 6 <input type="date" class="form-control" id="limitInput" name="limit"> 7 </div> 8 <button type="submit" class="btn btn-primary">新規追加</button> 9 </form>

実現したいこと

タスクリスト内のタスクを追加する際、タスクリスト内でのみタスク名の重複を禁止したい。
(MySQLでいう、複合ユニークキーの実現)

ex)
タスクリスト1内に、タスク1が存在し、タスク1を登録する→禁止
タスクリスト1内に、タスク1が存在する状況で、タスクリスト2内にタスク1を登録する->許可

発生している問題・エラーメッセージ

複合ユニークキーの設定方法がわかりません。
下記のバリデーションルールであれば、タスク名が重複する段階でバリデーションされてしまう

該当のソースコード

php

1<?php 2 3namespace App\Http\Requests; 4 5use Illuminate\Foundation\Http\FormRequest; 6 7 8class TaskRequest extends FormRequest 9{ 10 /** 11 * Determine if the user is authorized to make this request. 12 * 13 * @return bool 14 */ 15 public function authorize() 16 { 17 return true; 18 } 19 20 /** 21 * Get the validation rules that apply to the request. 22 * 23 * @return array 24 */ 25 public function rules() 26 { 27 return [ 28 'task_name' => 'required|min:1|max:31|unique:tasks,task_name'. $this->id. ',id,task_list_id'. $this->task_list_id, 29 ]; 30 } 31} 32

試したこと

下記の記事等を参考にさせていただきましたが、実現できませんでした。
http://tdsen.blog.jp/archives/33449990.html

初歩的な質問なのかもしれませんが、有識者の方、何卒お力添えをよろしくお願いいたします。

### 補足情報
下記のバリデーションを設定した場合、エラーが発生しました。

php

1<?php 2 3namespace App\Http\Requests; 4 5use Illuminate\Foundation\Http\FormRequest; 6use Illuminate\Validation\Rule; 7use App\Http\Requests\TaskRequest; 8 9class TaskRequest extends FormRequest 10{ 11 /** 12 * Determine if the user is authorized to make this request. 13 * 14 * @return bool 15 */ 16 public function authorize() 17 { 18 return true; 19 } 20 21 public function rules() 22 { 23 return [ 24 Validator::make($data, [ 25 'task_name' =>[ 26 Rule::unique('tasks')->where(function ($query){ 27 return $query->where('task_list_id', $data['task_list_id']); 28 }) 29 ], 30 ]->validate(); 31 ]; 32 }
ReflectionException Class App\Http\Requests\TaskRequest does not exist

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

この様な感じで如何でしょうか?
このサイトの「追加のWHERE節を付け加える」使えそうですが…

php

1Validator::make($data, [ 2 'task_list_id2' => [ 3 Rule::unique('tests')->where(function($query) use($data){ 4 return $query->where("task_list_id",$data["task_list_id"]); 5 }) 6 ], 7])->validate();

追記

私の環境ではこのカスタムリクエストクラスで動かせました。

php

1<?php 2 3namespace App\Http\Requests; 4 5use Illuminate\Foundation\Http\FormRequest; 6use Illuminate\Validation\Rule; 7use Illuminate\Http\Request; 8 9class TaskRequest extends FormRequest 10{ 11 /** 12 * Determine if the user is authorized to make this request. 13 * 14 * @return bool 15 */ 16 public function authorize() 17 { 18 return true; 19 } 20 21 /** 22 * Get the validation rules that apply to the request. 23 * 24 * @return array 25 */ 26 public function rules(Request $request) 27 { 28 return [ 29 'task_list_id2' => 30 Rule::unique('tests')->where(function($query) use($request){ 31 return $query->where("task_list_id",$request->task_list_id); 32 }) 33 ]; 34 } 35} 36

投稿2018/05/21 03:12

編集2018/05/21 04:49
motuo

総合スコア3027

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sabamiso

2018/05/21 03:57

ご回答ありがとうございます。 回答の通りに、コードを組み込ませていただきましたところ、補足のようなエラーが表示されました。 どのような対応を行えばよろしいでしょうか。 基礎的な質問で申し訳ありません。
motuo

2018/05/21 04:08

use App\Http\Requests\TaskRequest; いらないんじゃないですか?
sabamiso

2018/05/21 04:10

use App\Http\Requests\TaskRequest; を削除しましても、エラーは変わらぬままの状況です。 お手数おかけして申し訳ありません。
motuo

2018/05/21 04:28

エラー内容は App\Http\Requests\TaskRequest does not exist なので、これを読めない事がエラーの直接原因だと思いますよ。 requestではなく、controllerでエラーが起きているのではありませんか? このあたりも参考になると思います。 https://qiita.com/niiyz/items/5b83ef5255a1ec64d9d6 これにてこずるようでしたら、まずはControllerで直接Validationかけてみては?
sabamiso

2018/05/21 11:30

ご丁寧に自環境でも試していただき、ありがとうございます。 ぜひ、参考にさせていただきます。
guest

0

ベストアンサー

とりあえず、「,」 が沢山足りていないようですが、

php

1 2'task_name' => 3 ↓ここ              ↓ここ 4'required|min:1|max:31|unique:tasks,task_name,'. $this->id. ',id,task_list_id,'. $this->task_list_id,

質問掲載時の、書き間違いでしょうか??


追記します。

uniqueの後ろに指定できるのは、「ユニークチェック対象から除外する」条件です'task_name' =>
'required|min:1|max:31|unique:tasks,task_name,'. $this->id. ',id,task_list_id,'. $this->task_list_id
上記だと、・idが一致する・task_list_id が一致するのどちらかを満たす場合に除外されます。本来は、・idが一致する・task_list_id が一致しないのどちらかを満たす場合に、除外したいはず・・ですよね?なので、php'task_name' => //↓これでnot条件に'required|min:1|max:31|unique:tasks,task_name,'. $this->id. ',id,task_list_id,!'. $this->task_list_id,
が、設定すべき内容なのではないかと思われます。

書き直しますね・・・

uniqueの後ろに指定できるのは、「ユニークチェック」条件ですね!

1つめは条件一致で除外、2個目以降は条件一致で対象となります。

php

1'task_name' => 2'required|min:1|max:31|unique:tasks,task_name,'. $this->id. ',id,task_list_id,'. $this->task_list_id

つまり

・idが一致しない
・$this->task_list_idが一致する

の双方を満たすものからユニークチェックを行います。

で、新規作成時の話ですが、

$this->idは何か入っていますか??

-1とか0とか入っていれば大丈夫そうですが、nullの場合、想定の通りに動くのか謎です。
(やったことないので)

もし$this->id がnullなのであれば、バリデーションを

'task_name' => 'required|min:1|max:31|unique:tasks,tasks,task_name,'. intval($this->id). ',id,task_list_id,'. $this->task_list_id

のようにすれば、上手く行くかもです。

・・・何度も訂正を書いてしまったので、自分でも信頼性に欠ける回答だなと思っております。
すみません・・・

投稿2018/05/21 02:39

編集2018/05/21 07:10
mix-peach

総合スコア1910

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sabamiso

2018/05/21 03:49

自分のケアレスミスでありました。 ご指摘の通り、修正させていただきました。 しかし、バリデーションチェックでの重複禁止が通らず、重複したデータを追加してしまいます。
mix-peach

2018/05/21 07:11 編集

回答追記後に、説明文が間違っていたことに気づきました。。すみません ><;  回答はまるごと訂正させていただきました・・
sabamiso

2018/05/21 07:24

丁寧な説明ありがとうございました。 $this->idは、autoインクリメントであるため、nullになっている思うので、intvalを使用すると、予想通りの挙動をしてくれました! ありがとうございます。 ちなみに、回答修正前の方法も試させていただきましたが、そちらも要望どおりの挙動をしてくれましたので、ご報告させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問