eggplantSword's avatar

Get count of items by nested array

I'm trying to get counts of the items in my collection my the user's role. This is the code

// Last Locations
        $locations = Location::query();
        $locations->select('*')->selectRaw('ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY datetime DESC) AS "row_number"');

//other queries

//Current Locations
        $currentLocations = Location::with('user.roles')->fromSub($locations, 'locations')->where('row_number', 1);

this is the data structure, in this case I would need to count by Back Office (and the other role names) from $currentLocations' relationship, another thing is that user.roles is an array but it always only has one.

{
   "id":"5c4c6c2f-c8c4-471c-ac25-683f4c4e39ad",
   "latitude":"13.678361",
   "longitude":"-89.2750312",
   "battery":38,
   "precision":23.985000610352,
   "angle":"0.00",
   "speed":"0.00",
   "altitude":"915.00",
   "datetime":"2024-01-22T23:54:13.000000Z",
   "user_id":"9a76eae4-9e4c-4591-a99f-17e1972bb500",
   "created_at":"2024-01-23T06:02:09.000000Z",
   "updated_at":"2024-01-23T06:02:09.000000Z",
   "row_number":1,
   "user":{
      "id":"9a76eae4-9e4c-4591-a99f-17e1972bb500",
      "uuid":"71a0fe03-aff2-47bd-bb6e-8975755e71a5",
      "name":"user",
      "email":"[email protected]",
      "is_active":1,
      "created_at":"2023-10-27T03:22:56.000000Z",
      "updated_at":"2023-10-27T03:22:56.000000Z",
      "can_export_db":false,
      "roles":[
         {
            "id":3,
            "name":"Back Office",
            "guard_name":"web",
            "created_at":"2023-09-19T23:16:16.000000Z",
            "updated_at":"2023-09-19T23:16:16.000000Z",
            "pivot":{
               "model_id":"9a76eae4-9e4c-4591-a99f-17e1972bb500",
               "role_id":3,
               "model_type":"App\Models\Tenant\User"
            }
         }
      ]
   }
}
#

I have this example, but I'm unsure how to use it with the relationship I mentioned above since it's in an array

$countSalePointCheckOuts = SalePointCheckOut::query();
$countSalePointCheckOuts->selectRaw(
            "SUM(CASE WHEN sale_point_entry = ? AND sale_point_exit = ? THEN 1 END) AS visited",
            [true, true]
        );
0 likes
2 replies
antoniovpires's avatar

Could you use something like this?

$roleCounts = $currentLocations->groupBy(function ($location) { $role = optional($location->user->roles->first())->name;

return $role ?? 'Unknown';

})->map->count();

amitsolanki24_'s avatar

@msslgomez Try this

    $currentLocations = Location::with('user.roles')
    ->withCount([
           'user.roles' => function($query){
                    $query->where('name','Back Office');
           }
     ])

Please or to participate in this conversation.