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

実現したいこと

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

コメントを投稿

0 コメント