Search code examples
laraveleloquentlumen

Lumen/Laravel: count every nested relationship


i've got these nested relationship in Lumen 8, i'm looking for an Eloquent solution, if it's possible, to show the count of each nested relationship.

Procedures ->(hasMany) Documents ->(hasMany) DocumentFiles

I want to count DocumentFiles but on Documents. (field document_files_count)

So if i've got 1 Procedure with 2 Documents with 1 File each, i want to have a document_files_count on every Document object counting 1.

That's like what i'm expecting to have when returning the Procedure Object:

{
    "id": 1,
    "title": "Exercitationem ea distinctio consectetur.",
    "description": "Deserunt perferendis impedit laboriosam nemo hic unde est et. Quia dolores tempora incidunt iste dolor fugiat harum quae. Ducimus sit quo ut recusandae rerum qui.",
    "expiry": "2021-05-31 04:51:15",
    "status": "hidden",
    "documents_count": 1,
    "documents": [
        {
            "id": 1,
            "procedure_id": 1,
            "title": "docname",
            "description": "Lorem ipsum ",
            "document_files_count": 1
            "document_files": [
                {
                    "id": 1,
                    "document_id": 1,
                    "path": "path_to_file",
                    "extension": null,
                    "size": 34020,
                }
            ]
        },
        {
            "id": 2,
            "procedure_id": 1,
            "title": "docname2",
            "description": "Lorem ipsum 2",
            "document_files_count": 1
            "document_files": [
                {
                    "id": 1,
                    "document_id": 1,
                    "path": "path_to_file",
                    "extension": null,
                    "size": 34020,
                }
            ]
        }
    ]
}

I've also set an hasManyThrough relation into Procedure model to access document files data from Procedure.. but doing withCount(['documentFiles']) obviously give me the general procedure documents and not the files per document count.

public function documentFiles(){
    return $this->hasManyThrough(DocumentFile::class, Document::class);
}

Many thanks!!


Solution

  • If you have a HasMany (or reverse of it) relation, you can do NAME_OF_RELATION_count. In your case, it would be documentFiles_count and that would give you back the number of models that particular relation has.

    So, let's say you want to get each number, you do something like this:

    $procedures = Procedure::with('documents.documentsFiles')->all();
    $eachDocumentsFiles = collect();
    
    foreach ($procedures as $procedure) {
        foreach ($procedure->documents as $document) {
            $eachDocumentsFiles->push($document->documentFiles_count);
        }
    }
    

    Have in mind that this code is not 100% performant, I just coded like that because I have no code to work with. But the magic is using ->relation_name_count, in your case ->documentFiles_count.

    If this is not working, you will have to use withCount (but I am not sure if it is available in Lumen).