Models relation not working when trying to get the children models in Laravel

I’m having a model Question that belongs to model Exam. Exam can have many questions (one-to-many relation). I’ve no problem with storing the data, but when I try to get the questions for the exam with Exam::find($exam->id)->questions; I get NULL. I’ve dd the result for Exam::find($exam->id) and the relations are empty: #relations: [].

This is how I’ve registered my Question model:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Question extends Model
{

    public $timestamps  = false;
    protected $fillable = ['question', 'correct_answer', 'category_id', 'type'];

    public function questionCategory():belongsTo {
        return $this->belongsTo(QuestionCategory::class);
    }

    public function exam(): BelongsTo {
        return $this->belongsTo(Exam::class);
    }
}

And this is the Exam model:

namespace App\Models;


use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Exam extends Model
{
    public $timestamps = false;
    protected $fillable = ['name'];

    public function question(): HasMany
    {
        return $this->hasMany(Question::class);
    }
}

Here is the DB schema for the question’s table from the migration file:

Schema::create('questions', static function (Blueprint $table) {
            $table->id();
            $table->string('question');
            $table->integer('correct_answer')->nullable();
            $table->integer('question_category_id')->default(1);
            $table->integer('exam_id');
            $table->string('type')->default('text');
        });

Also this is how I’m saving the data for the questions:

$request->validate([
    'examId' => ['required', 'numeric'],
    'questions' => 'required'
]);

$exam = Exam::find($request->input('examId'));
$questions = $request->input('questions');

foreach ($questions as &$question_entry) {
    // create the question if it doesn't exist
    if ((int)$question_entry['id'] === 0) {
        $question = new Question();
    } else {
        $question = Question::find($question_entry['id']);
    }

    $question->exam_id = $exam->id;
    $question->question = $question_entry['body'];
    $question->type = $question_entry['type'];
    $question->question_category_id = $question_entry['category'];
    $question->save();     
}

The saving to the DB is successful and I can see the entries in the DB. And if I try to do something like Question::where('exam_id',1)->get() I will get the questions from that exam, but I don’t understand why when I try to get the results from the parent model (like Exam::find(1)->questions) I get NULL`. It seems like there is no relation between the two models.

I’m using Laravel 10 with Homestead and Breeze.

>Solution :

Is see you are using the singular question in your relation definition in the Exam model.
That could be the reason why it is null.

Did you also try the plural questions, like this:

public function questions(): HasMany
{
    return $this->hasMany(Question::class);
}

The rest of the code seems fine, but you could also create the foreign id like this:

$table->foreignId('exam_id');

You can read more about foreign keys in the documentation

Leave a Reply