Level 56
In summary you need to either keep track of used answers, or remove them from the available pool.
I used the keep track option. Have fun =)
public function generate(Request $request, $unit_id)
{
$unit_id = WordUnit::find($unit_id);
$words = Vocabulary::where('unit_id', $unit_id->id)->get();
$vocaquiz = VocaQuiz::insertGetId([
'student_id' => auth()->user()->id,
'unit_id' => $unit_id->id,
'quiz_uniq_code' => uniqid(15),
]);
if (! $vocaquiz) {
toast('Something was wrong', 'danger');
return redirect()->back();
}
// this will keep track of all selected answers
$usedAnswers = [];
for ($i = 0; $i < 50; $i++) {
$correctAnswer = $words
// filters out already selected items
->whereNotIn('azw', $usedAnswers)
->random();
$usedAnswers[] = $correctAnswer->azw;
$question = $correctAnswer->enw . ' - ???';
$answers = collect();
foreach (range(1, 4) as $option) {
$answer = $words
->where('speech', $correctAnswer->speech)
// I assuemed no repeated answers are desired.
// But if it is a vocabulary quiz, such as looking for synonims
// replace `$usedAnswers` with `$answers->all()` so only
// the answers already used in this questions are avoided
->whereNotIn('azw', $usedAnswers)
->random()
->azw;
$answers->push($answer);
$usedAnswers[] = $answer;
}
$answers->push($correctAnswer->azw);
// I added this to randomize
// the correct option order. before
// it would be always the fifth option.
// Remove if unnecessary
$answers = $answers->shuffle();
VocaTest::insert([
'quiz_id' => $vocaquiz,
'ques' => $question,
'opt1' => $answers[0],
'opt2' => $answers[1],
'opt3' => $answers[2],
'opt4' => $answers[3],
'opt5' => $answers[4],
'correct' => $correctAnswer->azw,
'created_at' => Carbon::now(),
]);
}
toast('Quiz generated! Check: Ready Quizzes', 'success');
return redirect()->back();
}