VMeijer
VMeijer

Reputation: 433

Laravel: Order hasManyThrough

I struggle to understand the "hasManyThrough" concept in laravel. I got something similar to these tables:

project
- id

project_document
- id
- project_id

project_document_order
- id
- project_document_id

In the project model I've got these relations:

public function projectDocuments(){
    return $this->hasMany(
        ProjectDocuments::class,
        'project_id'
    );
}

public function projectDocumentOrder(){
    return $this->hasManyThrough(
        ProjectDocumentOrder::class,
        ProjectDocuments::class,
        'project_id',
        'project_document_id'
    );
}



Project::where( 'id', $pid )->with( 'projectDocuments', 'projectDocumentOrder' )->firstOrFail();

This results in one project with multiple projectDocuments and multiple projectDocumentOrder.

Result:

#original: array:14 [▼]
"id" => 1
"uuid" => [UUID]
"author" => 1
"project_name" => [NAME]

#relations: array:2 [▼]
"projectDocuments" => Illuminate\Database\Eloquent\Collection {#1352 ▼
    #items: array:5 [▼
        0 => App\Models\projectDocuments {#1368 ▼
            #original: array:10 [▼
                "id" => 1
                "user_id" => 471
                "project_id" => 1
        }
        1 => App\Models\projectDocuments {#1368 ▼
            #original: array:10 [▼
                "id" => 2
                "user_id" => 252
                "project_id" => 1
        }
        2 => App\Models\projectDocuments {#1368 ▼
            #original: array:10 [▼
                "id" => 3
                "user_id" => 252
                "project_id" => 1
        }
        3 => App\Models\projectDocuments {#1368 ▼
            #original: array:10 [▼
                "id" => 4
                "user_id" => 471
                "project_id" => 1
        }
        4 => App\Models\projectDocuments {#1368 ▼
            #original: array:10 [▼
                "id" => 5
                "user_id" => 252
                "project_id" => 1
        }
    ]
}
"projectDocumentOrder" => Illuminate\Database\Eloquent\Collection {#1367 ▼
  #items: array:5 [▼
        0 => App\Models\projectDocumentOrder {#1368 ▼
            #original: array:10 [▼
                "id" => 1
                "project_documents_id" => 1
                "order" => 1
        }
        1 => App\Models\projectDocumentOrder {#1368 ▼
            #original: array:10 [▼
                "id" => 2
                "project_documents_id" => 1
                "order" => 2
        }
        2 => App\Models\projectDocumentOrder {#1368 ▼
            #original: array:10 [▼
                "id" => 3
                "project_documents_id" => 1
                "order" => 3
        }
        3 => App\Models\projectDocumentOrder {#1368 ▼
            #original: array:10 [▼
                "id" => 4
                "project_documents_id" => 1
                "order" => 5
        }
        4 => App\Models\projectDocumentOrder {#1368 ▼
            #original: array:10 [▼
                "id" => 5
                "project_documents_id" => 1
                "order" => 4
        }
    ]
}

Now my question: how would I go about ordering projectDocuments based on the order column in projectDocumentOrder?

Upvotes: 0

Views: 916

Answers (2)

VMeijer
VMeijer

Reputation: 433

I found a solution that works for me.

$project->projectDocumentOrder->sortBy( 'order' )->pluck('projectDocuments')->toJson()

This solution does require having a projectDocuments function linking the ProjectDocumentOrder to the ProjectDocuments in the ProjectDocumentOrder model.

Upvotes: 0

João Campos
João Campos

Reputation: 21

First I think you only need the with: 'projectDocumentOrder', because laravel to get to projectDocumentOrder, will need to join projectDocuments.

Second You could do something like:

Project::where( 'id', $pid )->with(['projectDocuments'=>function($query){
   $query->leftJoin('table_name','local_key','operator','foreign_key');
   $query->orderBy('table_name.field','ASC|DESC');
)
}])->firstOrFail();

Upvotes: 1

Related Questions