lighthouse icon indicating copy to clipboard operation
lighthouse copied to clipboard

@withCount returning Data instead of count

Open pkatuwal opened this issue 4 years ago • 5 comments

Describe the bug After I updated lighthouse from 4.14.1 to 4.15.0, @withCount and @count is returning data instead of number of data in relations.

Expected behavior/Solution

Schema defination

type User{
 #totalAssignClient: Int! @count(relation:"countAssignedClients") @cache(maxAge:500 private:true)
 totalAssignClient: Int! @withCount(relation:"countAssignedClients") @cache(maxAge:500 private:true)
}

** My Class Model**

public function countAssignedClients()
{
        return $this->hasMany(ClientFollowUpLoadInfo::class)->whereIn('current_status', ['assigned']);
}

Output/Logs

Click to expand
# On 4.14.1
{
  "data": {
    "userByBranch": [
      {
        "username": "bibek.shrestha",
        "id": "2",
        "countTotalAssignedClients": 5
      },
      {
        "username": "pramod.katuwal",
        "id": "1",
        "countTotalAssignedClients": 9
      },
      {
        "username": "niki.maharjan2",
        "id": "3",
        "countTotalAssignedClients": 0
      },
      {
        "username": "pujan.piya",
        "id": "21",
        "countTotalAssignedClients": 0
      },
      {
        "username": "nivesh.acharya",
        "id": "141",
        "countTotalAssignedClients": 0
      }
    ]
  }
}

# On **^4.14**
{
      "debugMessage": "Expected a value of type \"Int\" but received: [{\"id\":81,\"unique_identifier\":\"uouN9GT8pnqXC0htzc79:MjAyMC0wNS0yNSAxNzo0OTozNw==\",\"created_by\":\"pramod\",\"current_assignment\":\"2\",\"current_status\":\"assigned\",.....................
}

Lighthouse Version 4.15.0

pkatuwal avatar Jul 02 '20 07:07 pkatuwal

Probably related to https://github.com/nuwave/lighthouse/pull/1390

A PR with a failing test case in https://github.com/nuwave/lighthouse/blob/master/tests/Integration/Schema/Directives/CountDirectiveDBTest.php should be a great start for a fix.

spawnia avatar Jul 02 '20 08:07 spawnia

I tried Two way to check why its not working , so found following Findings

Observation Class

vendor/nuwave/lighthouse/src/Schema/Directives/CountDirective.php ->resolveField()
  1. If i keep different name of query than relation , Nodename is not found inside Model class.
#different relation and name
countTotalAssignedClients: Int @count(relation:"countAssignedClients")
if (! is_null($relation)) {
//$this->nodeName() results countTotalAssignedClients
//but problem is $model class is Expecting counttotalassignedclients
return $model->{$this->nodeName()}; //null
return dd($model->counttotalassignedclients); //changing to lower is worked., 
}

Solution for condition 1

return $model->{strtolower($this->nodeName())}; //not logical :(
  1. Keeping query object and relation same
countAssignedClients: Int! @count(relation:"countAssignedClients")
return $model->{$this->nodeName()} //return correct relation and try to get relation data

// here missing relational count method to get counting data.

Solution for condition 2

return $model->{$this->nodeName()}->count();

Solution for Both

return $model->{$relation}()->count();

pkatuwal avatar Jul 02 '20 17:07 pkatuwal

@withCount is not meant to return a value since it only implements FieldMiddleware. Useful when you are resolving a field that uses a relationship count within the resolver. @withCount ensures that the model eager loads the count before your resolver.

A simple @count should do what you need:

countAssignedClients: @count(relations: "clients", scopes: ["assigned"])
User extends Model {
    public function clients(): HasMany
    {
        return $this->hasMany(Client::class);
    } 
}


Client extends Model {
    public function scopeAssigned(Builder $query): Builder
    {
        return $query->whereIn('current_status', ['assigned']);
    } 
}

tlaverdure avatar Jul 09 '20 21:07 tlaverdure

@tlaverdure right, thank you.

@pkatuwal please try @count and report back with results. Given we have test cases for this functionality and it is working for others, i am closing this issue.

spawnia avatar Jul 10 '20 06:07 spawnia

@spawnia sorry for late reply . I have tried everything as @tlaverdure suggested. But still it is not working. I tested many ways to solve this issues and finally i got issued on field name.

Not working

countAssignedClients: Int @count(relations: "clients", scopes: ["assigned"])

Working

countassignedclients: Int @count(relations: "clients", scopes: ["assigned"])

//or
count_assigned_clients: Int @count(relations: "clients", scopes: ["assigned"])


In this case camelCase fails to return @count results.

pkatuwal avatar Jul 24 '20 07:07 pkatuwal