Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Griddart's avatar

Learning about relations within Laravel

Hello,

I am fairly new to Laravel and have been following a bunch of tutorials. I am now trying to create a simple quiz application to learn more, but I might use some advice.

In the application it is possible to create multiple quizzes. Each quiz has multiple questions and each question has multiple answers. I've made the relations between them like so:

Quiz model


public function questions(){

    return $this->hasMany(Question::class);

}

Question model


public function answers(){

        return $this->hasMany(Answer::class);

}

public function quiz(){

        return $this->belongsTo(Quiz::class);

}

Answer model


public function question(){

        $this->belongsTo(Question::class);

}

So far it ain't that complicated and I think it's fine, but I am trying to add a extra model called Result that remembers which question the user is currently in. It should do more in the future but so far it contains a quiz_id and a question_number. I added the relation within the quiz model like so:


public function result(){

        return $this->hasOne(Result::class);

}

Everytime the user opens the url quiz/ it calls a controller method:

public function show(Quiz $quiz)
    {

        $result = $quiz->result;

        $questions = $quiz->questions->toArray();

        foreach($questions as $data){

            if($data['id'] == $result->question_number){

                $question = Question::find($data['id']);
                break;

            }

        }

        $answers = $question->answers;

        return view('website.quiz.show', compact('quiz', 'question', 'answers'));

    }

This code actually works fine it shows the question with it's answers according to the question_number in Result. But I think it's not the way it should be done and it does not feel right to get all questions with a query when I only need one.

So my question is could someone push me a little more into the right direction in how I should setup the controller? Or am I doing it wrong entirely?

0 likes
2 replies
aurawindsurfing's avatar

You do not need any of those in your show function.

Once you pass quiz to the view

return view('website.quiz.show', compact('quiz'));

then laravel will know all of its relations so you can just call them while displaying them.

Co call them directly in blade:

$quiz->result;
$quiz->questions->pluck('id');
Griddart's avatar

Hello thank you for the reply.

I've been experimenting and I found some solution but I don't know exactly what you meant, I will try to explain what I am missing.

So the result model only contains a quiz_id and a question_number column ( question_number will be later linked to a question. ). But this means there is not really a relation between result and the question. My controller looks now like this when your visit /quiz/1:

    public function show(Quiz $quiz)
    {

        $question = Question::find($quiz->result->question_number);

        if(!empty($question)){

            return view('website.quiz.show', compact('quiz', 'question'));

        }

        return view('website.quiz.finish');

    }

So my quiz searches for the question according to the question_id it is currently in.

In my view I render the values like so:

@extends('website.master')

@section('content')

    <div class="panel-body">

        {{ $quiz->name }}

        <div class="row">

            <div class="col-md-12">

                {{ $question->text }}
                <br><br>

                <form method="POST" action="{{ $quiz->path() }}">
                    {{ csrf_field() }}

                    @foreach($question->answers as $answer)

                        <button class="btn btn-primary" name="answer" value="{{ $answer->id }}">{{ $answer->text }}</button>
                        <br>
                        
                    @endforeach 
                </form>

            </div>

        </div>
        
    </div>

@endsection

Does it makes any sense what I am doing? How could I improve?

Please or to participate in this conversation.