質問するログイン新規登録
Laravel

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

Q&A

解決済

1回答

963閲覧

Laravelにて、特定のID毎にユニークなデータを作成したい。

AhMou-YO

総合スコア1

Laravel

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

0グッド

0クリップ

投稿2023/04/24 07:17

0

0

実現したいこと

Laravel8にて、テストデータを作成しています。テストデータはユーザーID単位でユニークなIDを得るように操作したいと思っています。

前提

LaravelのFactory機能を利用して作成しています。

以下の構文で実現するものと思って記述しました。

// ユーザー毎に店を決める public function specify_user($user_id) { return $this->state(function (array $attributes) use ($user_id) { $temp_val = $user * 100; return [ 'user_id' => $user_id, 'shop_id' => $this->faker ->unique() ->numberBetween(1 + $temp_val, 20 + $temp_val) - $temp_val, ]; }); }

なお、呼び出し側は以下のように、作成数は乱数となっています。

public function run() { for($i = 1; $i < 11 ; $i++){ $choice = Choice::factory() ->count(random_int(0, 5)) ->specify_user($i) ->create(); } }

このコードでは時たまうまくいきますが、100%ではありません。乱数の発生次第ではエラーが発生します。

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

発生するエラーは乱数計算の上限に達したとのメッセージが発生します。

In UniqueGenerator.php line 80: Maximum retries of 10000 reached without finding a unique value

試したこと

被らないようにチェックするようにしたコードに置き換えてみましたが、やはり、うまくいきません。

public function specify_user($user_id) { return $this->state(function (array $attributes) use ($user_id) { $temp_val = $user_id * 100; $used_numbers = \DB::table('favorites') ->where('user_id', $user_id) ->pluck('restrant_id') ->toArray(); $restaurant_id = $this->uniqueRandomNumber(1 + $temp_val, 20 + $temp_val, $temp_val, $used_numbers); return [ 'user_id' => $user_id, 'restrant_id' => $restaurant_id, ]; }); } public function uniqueRandomNumber($min = 1, $max = 20, $temp_val = 0, $exclude = []) { $number = $this->faker->numberBetween($min, $max) - $temp_val; $attempts = 0; while (in_array($number, $exclude) && $attempts < 10000) { $number = $this->faker->numberBetween($min, $max); $attempts++; } if ($attempts == ($max - $min)) { throw new \Exception("All numbers between $min and $max have been used."); } return $number; }

こちらのコードの場合は、ユーザーID単位でユニークなIDが大概算出できず、

SQLSTATE[23000]: Integrity constraint violation

でエラーになります。

補足情報(FW/ツールのバージョンなど)

Laravel : 8.83.26

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

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

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

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

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

guest

回答1

0

自己解決

トレースする方法が今まで不明でしたが、echo分であればコンソール出力することがわかり、トレースできました。

結果、関数が原因でなく、

public function definition() { return [ 'user_id' => $this->faker->numberBetween(2,11), 'shop_id' => $this->faker->unique()->numberBetween(1,20), ]; }

どんな場合でもこのコードが最初に実行されて、このuniqueがエラーメッセージを発していることがわかりました。
これを利用していない場合は、"unique"を削除すればよかったということです。

なお、算出するための関数ですが、正しく無いようでしたが、ここでは原因が判明したので、割愛します。

投稿2023/04/26 05:06

AhMou-YO

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問