Home > Enterprise >  How to count each rows ID of tables relationship using laravel?
How to count each rows ID of tables relationship using laravel?

Time:06-03

so I have a 5 tables in my database with pivot, Countries, Cities, Shops, Users, shop_employee their relationship is this

Countries  | Cities      | Shops     | shop_employees| Users 
 id        | country_id  | city_id   |  shop_id      | id
                                        employee_id

my goal is I want to count each City, shop, employees in the Country

this is my controller

class CountryController extends Controller
{
    public function country(){
       $countries = Country::with(['cities.shops.employees'])->get();
       return view('country',['countries'=>$countries]);
    }
}

this is my model Country

class Country extends Model
{
    public function cities(){
        return $this->hasMany(City::class);
    }
}

this is my model City

class City extends Model
{
    public function shops(){
        return $this->hasMany(Shop::class);
    }
}

this is my model Shops

class Shop extends Model
{
    public function employees(){
        return $this->belongsToMany(User::class,'shop_employees','shop_id','employee_id');
    }
}

this is my view

        <table >
                <thead>
                  <tr>
                    <th >Country</th>
                    <th >City</th>
                    <th >Shop</th>
                  </tr>
                </thead>
                <tbody>
                @foreach ($countries as $country)
                <tr >
                    <td >{{ $country->name }}</td>
                    <td >{{ $country->cities->count() }}</td>
                    <td ></td>
                  </tr>
                @endforeach
                </tbody>
              </table>

I tried this code its working fine the City is counting

{{ $country->cities->count() }}

the output, in this output I want to display the count of shops and employee

enter image description here

but when im trying this code it gives me a error

  $country->cities->shops->count() or
  $country->cities->shops->employees->count() 

error: Property [shops] does not exist on this collection instance

CodePudding user response:

You can try to get the aggregate with the query itself

class CountryController extends Controller
{
    public function country(){
        $countries = Country::with([
            'cities' => fn($query) => $query->withCount('shops'),
            'cities.shops' => fn($query) => $query->withCount('employees'),
            'cities.shops.employees'
        ])
       ->withCount('cities')
       ->get();

       return view('country',['countries'=>$countries]);
    }
}

Then you can access the aggregate values as

//Get the count of cities under the country
$country->cities_count; 

foreach($countries as $country) {
    $noOfCities = $country->cities_count;

    $noOfShops = $country->cities->sum('shops_count');

    $noOfEmployees = $country->cities->reduce(
        fn($carry, $city) => $carry   $city->shops->sum('employees_count')
    );
}

Laravel Docs - Eloquent Relationships - Aggregating Related Models

CodePudding user response:

You can achieve this by using the addSelect method Using subquery and passing a closure

Country::withCount('cities as city_count')
  ->addSelect([
    'shop_count' => Shop::selectRaw('count(*)')
    ->whereIn(
      'city_id',
       City::select('id')->whereColumn('country_id','countries.id'))
    ->limit(1), 
  ])
  ->addSelect([
    'employee_count' => DB::table('shop_employees')->selectRaw('count(*)')
    ->whereIn(
    'shop_id',
     Shop::select('id')
         ->whereIn(
           'city_id',
            City::select('id')->whereColumn('country_id','countries.id')
          )
     )->limit(1), 
  ])
  ->get();
  • Related