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

PetroGromovo's avatar

How to use hasManyThrough with reference to morph table?

On laravel site with 3 related tables :

            Schema::create('users', function (Blueprint $table) {
                $table->id();
                $table->string('name');
                $table->string('email')->unique();
                ...
    
    
            Schema::create('news', function (Blueprint $table) {
                $table->id('id');
                $table->string('title', 255);
                $table->mediumText('content');
                $table->string('content_shortly', 255)->nullable();
                ...
                $table->foreignId('creator_id')->nullable()->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
                ...
    
    
            Schema::create('complains', function (Blueprint $table) {
                $table->id();
                $table->foreignId('user_id')->nullable()->references('id')->on('users')->onDelete('CASCADE');
                $table->morphs('model');
                $table->timestamp('created_at')->useCurrent();

    ```
    
    
Field news.creator_id is ref to users table
    
In app/Models/User.php I have using hasManyThrough method:

    public function complainsOnNews()
    {
        return $this->hasManyThrough(
            Complain::class,
            News::class,
            'creator_id', // Foreign key on the news table...
            'model_id', // Foreign key on the Complains table...
            'id', // Local key on the complains table...
            'id' // Local key on the News table...
        );
    }
with request :

dd($this->profileUser->complainsOnNews);
I trace next sql :

    ```
SELECT `complains`.*, `news`.`creator_id`     AS `laravel_through_key`
        FROM `complains`
        INNER JOIN `news` on `news`.`id` = `complains`.`model_id`
        WHERE `news`.`creator_id` = 1

It is almost valid, but reference to complains.model_type missing some in some cases results would be wrong, it there some other models , not news

How that can be done ?

    "laravel/framework": "^10.48.7",

Thanks in advance!

0 likes
2 replies
drgreen's avatar
drgreen
Best Answer
Level 28

You could add a where clause for that:

public function complainOnNews()
{
    return $this->hasManyThrough(
        Complain::class,
        News::class,
        'creator_id', // Foreign key on News table...
        'model_id', // Foreign key on Complains table...
        'id', // Local key on User table...
        'id' // Local key on News table...
    )->where('model_type', News::class);
}
1 like

Please or to participate in this conversation.