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

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

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

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

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

Q&A

解決済

2回答

1670閲覧

Laravel8 2つのカラムのバリデーション方法

seven_7

総合スコア7

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

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

0グッド

0クリップ

投稿2021/12/06 09:06

編集2021/12/08 10:39

選手登録フォームを作成しています。
選手登録フォームからデータ登録する際に未定義であるという下記のエラーがでております。

Call to undefined method Illuminate\Contracts\Validation\Rule::unique()

##実現したいこと1
テーブルの「team_owner_id」で絞り込んでから「player_no」をuniqueとしてバリデーションしたい。
例:team_owner_idが1、player_noが10が既に登録済みとした場合
team_owner_idが1、player_noが10の登録はできない。
team_owner_idが2、player_noが10の登録はできる。

##テーブル playersテーブル
team_owner_idは、別で作成済みのteam_ownerテーブルとリレーションしています。
イメージ説明

###前提
選手登録をするteam_ownerは、ログインをしておりAuth::id()とteam_owner_idの数字は同じである。
選手登録をするcreate.blade.phpは、他のteam_owner_idを選択することはできない。

PlayerController

1public function store(Request $request) 2 { 3 $request->validate([ 4 'player_no' => [new Player_no_check], 5 6 ]); 7 8 $player = new Player(); 9 $player->team_owner_id = Auth::id(); 10 $player->player_no = $request->player_no; 11 $player->player_name = $request->player_name; 12 $player->save(); 13 // dd($player); 14 return redirect() 15 ->route('team_owner.players.index') 16 ->with([ 17 'message' => '選手登録をしました。', 18 'status' => 'info' 19 ]); 20 }

※下記のバリデーションは自分が分かりやすくなるように「player_no」のみ指定しています。

Rule\Player_no_check

1public function passes($attribute, $value) 2 { 3 return [ 4 'player_no' => Rule::unique('players')->where(function ($query) { 5 return $query->where('team_owner_id', 1); 6 }) 7 ]; 8 }

##参考にしたサイト
参考サイト1

参考画像:Laravelmanualより
参考キャプチャ

##試してみたこと1
参考サイトなどをみて、「Player_no_check.php」のようにバリデーションルールを作成したつもりでしたが
記述が間違っているようで未定義となっております。

ここからがどうして良いのかわからず質問にいたりました。

どのようにするとバリデーションを希望のバリデーションを通すことができますでしょうか。

どうぞよろしくお願いいたします。

##現在でているエラー内容
修正後の記述

player_no_check.php

1namespace App\Rules; 2 3// use Illuminate\Contracts\Validation\Rule; 4use Illuminate\Validation\Rule; 5use App\Models\Team_owner; 6use App\Models\Player; 7 8 9 10class Player_no_check extends Rule 11{ 12 /** 13 * Create a new rule instance. 14 * 15 * @return void 16 */ 17 public function __construct() 18 { 19 // 20 } 21 22 /** 23 * Determine if the validation rule passes. 24 * 25 * @param string $attribute 26 * @param mixed $value 27 * @return bool 28 */ 29 public function passes($attribute, $value) 30 { 31 dd($attribute, $value); 32 return [ 33 'player_no' => Rule::unique('players')->where(function ($query) { 34 return $query->where('team_owner_id', 1); 35 }) 36 ]; 37 } 38 39 /** 40 * Get the validation error message. 41 * 42 * @return string 43 */ 44 public function message() 45 { 46 return 'The validation error message.'; 47 } 48}
Error Object of class App\Rules\Player_no_check could not be converted to string

##試してみたこと2

下記の記述を試したところ「syntax error, unexpected ';', expecting ']'」が表示されました。

Player_no_check.php

1 public function passes($attribute, $value) 2 { 3 return [ 4 'player_no' => Player::where('player_no',$value) 5 ->where('team_owner_id', 1) 6 ->doesntExist(); 7 ]; 8 }

下記に変更をすると「syntax error」はなくなりましたが記述が合っているか自信がありません。

Player_no_check.php

1public function passes($attribute, $value) 2 { 3 4 return [ 5 'player_no' => Player::where('player_no', $value) 6 ->where('team_owner_id', 1)->doesntExist(), //「;」を「,」に変更 7 ]; 8 }

PlayerController

1public function store(Request $request) 2 { 3 $request->validate([ 4 'player_no' => [new Player_no_check], 5 6 ]); 7 8 $player = new Player(); 9 $player->team_owner_id = Auth::id(); 10 $player->player_no = $request->player_no; 11 $player->player_name = $request->player_name; 12 $player->save(); 13 // dd($player); 14 return redirect() 15 ->route('team_owner.players.index') 16 ->with([ 17 'message' => '選手登録をしました。', 18 'status' => 'info' 19 ]); 20 } 21

この状態で選手の新規登録をおこないました。

結果としては、登録がなんでもできてしまいバリデーションが効いていないような感じになっています。
現在のteam_owner_idが1、player_noを10として何度も登録ができてしまう状態です。

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

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

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

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

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

guest

回答2

0

ベストアンサー

すみませんでした。
詳しく調べた上、元のコードには問題ありません。
変更するべきコードはここだと思います。

php

1 public function passes($attribute, $value) 2 { 3 return Player::where('player_no',$value)->where('team_owner_id', 1)->doesntExist(); 4 }

変更前のであってます。

php

1use Illuminate\Contracts\Validation\Rule; 2 3class Player_no_check implements Rule

投稿2021/12/08 05:17

編集2021/12/09 11:46
skys215

総合スコア910

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

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

seven_7

2021/12/08 10:43

お返事ありがとうございます。 質問欄に試してみたこと2を追記いたしました。 教えていただいているのに、まだ躓いております。 申し訳ございません。 下記の記述の意味は、Playerモデルをまずplayer_noで絞り、その中からteam_owner_idが1のものがなければtrue、あればfalseの意味で理解しています。 この通り動けば確かにいけると思っておりますが、普通に登録ができてしまう状態です。 なぜ登録ができてしまうのかを模索中です。 ``` return [ 'player_no' => Player::where('player_no', $value) ->where('team_owner_id', 1)->doesntExist(), ]; ```
skys215

2021/12/09 01:12

登録できたplayerのteam_owner_idも同じですか?
seven_7

2021/12/09 02:51

お返事ありがとうございます。 はい、team_owner_idも同じになります。 (今回のteam_owner_idは1) team_ownerはログインをしておりまして、登録時は自分のteam_owner_idでしか登録ができない想定でいます。 現在は、team_owner_idが1の人がplayer_no10をなんども登録できてしまうということになります。
skys215

2021/12/09 11:47

回答を更新しました。passesはtrue/falseを返さなけらばいけません。arrayを返してたから、いつまでもtrueとなって登録ができてしまいました。
seven_7

2021/12/09 12:54

お返事ありがとうございました。 も、も、もしかしたらできたかもしれません! public function passes($attribute, $value) { $player = Player::where('player_no', $value) ->where('team_owner_id', Auth::id()); return $player->doesntExist(); } 上記のように記述をしたところ、team_owner_id「1」の人がplayer_no「10」の2回目を登録しようとしたらバリデーションがかかりエラーメッセージが表示されました。 他のplayer_noの場合はエラーがでずちゃんと登録することができました。 また、team_owner_id「2」の人のplayer_no「10」は登録ができまして、同じくもう1回「10」の登録はできずエラーが表示されました。 一応いまのところ希望の動作になったかと思われます。
seven_7

2021/12/09 14:08

skys215様 この度は、たくさんお時間をとっていただきありがとうございました。 いろいろと確認して一応希望の動作となりました。 個人的になかなか先が見えない中で、skys215様のご助言のおかげでなんとか 希望の動作ができました。 本当にありがとうございました。
guest

0

Illuminate\Contracts\Validation\Ruleではなく、

PHP

1use Illuminate\Validation\Rule;

に変えて試してください。

投稿2021/12/06 12:12

skys215

総合スコア910

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

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

seven_7

2021/12/06 12:32

お返事ありがとうございます。 Player_no_checkのuse文を変更しました。 変更前:use Illuminate\Contracts\Validation\Rule; 変更後:use Illuminate\Validation\Rule; エラー内容 App\Rules\Player_no_check cannot implement Illuminate\Validation\Rule - it is not an interface Ruleの実装ができない?というようなエラーがでてしまいました。 Ruleの実装にあたりもしかすると基本的な記述が足りていないのでしょうかね。 引き続き考えてみます。 お忙しいところ申し訳ございませんが、他にわかることなどありましたらよろしくお願いたします。
skys215

2021/12/06 13:31

class Player_no_check implements Ruleではなく、class Player_no_check extend Ruleに変えてみてください。
seven_7

2021/12/06 13:45

お返事ありがとうございます。 とりあえず記述変更をして試した結果のみの返信となります。 変更後:class Player_no_check extends Rule エラー内容:Class App\Rules\Player_no_check cannot extend from interface Illuminate\Contracts\Validation\Rule 拡張ができないエラーとなりました。 むむーなかなか難しいですね。
skys215

2021/12/06 15:35

すみません。二つとも変える必要があります。 変更前:use Illuminate\Contracts\Validation\Rule; 変更後:use Illuminate\Validation\Rule; 変更前:class Player_no_check implements Rule 変更後:class Player_no_check extends Rule
seven_7

2021/12/07 03:49

お返事ありがとうございます。 先程変更をして試してみました。 use Illuminate\Validation\Rule; class Player_no_check extends Rule エラー内容:オブジェクトが文字列に変換できない Object of class App\Rules\Player_no_check could not be converted to string 初めてみるエラーでしたので、どういったエラーなのか調べ中ではあります。 私が簡単なフォームの登録・保存・編集・更新・削除がやっとできるようになった初心者レベルですので理解には時間がかかりそうです。 似たような事例のサイトをいくつも見て理解を深めようとしておりますが、バリデーション部分だけでもなかなか奥が深いですね。
skys215

2021/12/07 14:13

エラーはどのファイルが吐き出したのですか? もしvendor/フォルダーじゃなかったら、コードをお願いします。
seven_7

2021/12/07 15:23

お忙しい中お返事ありがとうございます。 質問に「現在でているエラー内容」を追記いたしました。
seven_7

2021/12/07 15:25

エラーは新規登録(create.blade.php)に入力をして、登録ボタンを押したあとに追記をさせていただいたエラーが表示されました。
skys215

2021/12/08 03:56

いや、これは...vendor\laravel...フォルダーですね。 それともエラーのスクショをアップできますか?
seven_7

2021/12/08 04:09

仰っていることを理解できず申し訳ございません。 今、私が言っているエラー画面を質問欄に更新しました。 他にエラー出力される場所があるということでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問