Например есть модели User, Key, Prize.
В связующей таблице Reward поля user_id, key_id, prize_id каждому 10 выдается приз, но не больше 3 на юзера.
В случае сворачивания в транзакцию, какая либо из них может выполнится быстрее и тогда пользователь отравивший раньше запрос не получит приз.
public function index(Request $request)
{
$validator = Validator::make(
$request->all(),
$this->rules('index'));
if ($validator->fails()) {
return response()->json(
[
"message" => "Validation Errors",
"errors" => $validator->errors()
], 500);
}
$data = DB::transaction(function() use ($request)
{
$user = User::find($request->user_id);
$prize_count = $user->prizes()->count();
if ($prize_count >= 3) {
return response()->json([
"message" => "Register Code Error",
"errors" => 'Limit is exceeded'
], 500);
}
$key = Key::where('name', $request->code)->first();
$reward = new Reward([
'user_id' => $user->id,
'key_id' => $key->id
]);
$reward->save();
$rewards = Reward::orderBy('created_at', 'desc')->take(10)->get();
if ($rewards->where('prize_id', null)->count() < 10) {
return response()->json([
"message" => "Registered code"
]);
} else {
$random_prize = Prize::inRandomOrder()->first();
$reward->prize()->associate($random_prize);
$reward->save();
sleep(100);
return response()->json([
"message" => "Won",
"prize" => $random_prize
]);
}
});
return $data;
}