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

tetranyble's avatar

Eloquent relationship is not working

So yesterday i create a new project and declared some relationship. Here are my migration

    /**
     * 
	 * Thread migration
     *
     * @return void
     */
    public function up()
    {
        Schema::create('threads', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->unsignedBigInteger('user_id')->index();
            $table->text('body')->nullable();
            $table->timestamps();

            $table->foreign('user_id')->references('id')
                ->on('users')->cascadeOnDelete();
        });
    }

and the Reply migration

    /**
     * Reply migration.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('replies', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->unsignedBigInteger('thread_id');
            $table->text('body')->nullable();
            $table->timestamps();

            $table->foreign('user_id')->references('id')
                ->on('users')->cascadeOnDelete();
            $table->foreign('thread_id')->references('id')
                ->on('threads')->cascadeOnDelete();
        });
    }

Also here are the models

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Thread extends Model
{
    use HasFactory;

    protected $fillable = [ 'user_id', 'title', 'body' ];

    public function user(){
        return $this->belongsTo(User::class);
    }
    /**
     * Fetch a path to the current thread.
     *
     * @return string
     */
    public function path()
    {
        return '/threads/' . $this->id;
    }

    public function replies(){
        return $this->hasMany(Reply::class);
    }

}

Reply model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Reply extends Model
{
    use HasFactory;

    protected $fillable = ['user_id', 'body', 'thread_id'];

    public function owner(){
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    public function thread(){
        return $this->belongsTo(Thread::class, 'thread_id', 'id');
    }
}

the challenge is that i cannot get the replies even when i have records in my databse. this is my controller method.

 /**
     * Display the specified resource.
     *
     * @param  \App\Models\Thread  $thread
     * @return \Illuminate\Http\Response
     */
    public function show(Thread $thread)
    {
        $thread->load('replies');
        return view('threads.show', compact('thread'));
    }

However, when i use tinker session it works. I am using laravel 9.45. i cannot seem to understand what's going on. I am completely stucked.

0 likes
5 replies
Lara_Love's avatar

you need get $thread

$t = Threads::findorfail($thread);
return view .........
tetranyble's avatar

@LoverToHelp It is a single thread i am trying to load it's relationship. Again the actual thread is already in scope of the show method as it's a route model binding like so:

Route::get('/threads/{thread}', [\App\Http\Controllers\ThreadController::class, 'show']);

if dump thread, i get the thread but if dump replies like so: dd($thread->replies); i get empty collection.

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

Everything looks correct. I assume you don't get any errors.

Can you try using debugbar to see what queries are being run?

1 like
tetranyble's avatar

@Sinnbeck I saw the query through the debug bar and it turns out the seeder created more orphaned Thread without replies.

<?php

namespace Database\Seeders;

use App\Models\Reply;
use App\Models\Thread;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class ThreadSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Thread::factory(10)->create()->each(function ($thread){
            Reply::factory(5)->create(['thread_id' => $thread->id]);
        });
    }
}

I think something is wrong somewhere or it could be that i don't really understand how factories work. Here are the definition of my factory.

class ReplyFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            'body' => $this->faker->sentence,
            'user_id' => User::factory()->create()->id,
            'thread_id' => Thread::factory()->create()->id,
        ];
    }
}

and

class ThreadFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            'user_id' => User::factory()->create()->id,
            'title' => $this->faker->title,
            'body' => $this->faker->text,
        ];
    }
}

Please or to participate in this conversation.