如何使用 laravel 计算表关系的每一行 ID?

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

所以我的数据库中有 5 个表 pivotCountries, Cities, Shops, Users, shop_employee 他们的关系是这样

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

我的目标是我想统计国家/地区

中的每个城市、商店、员工

这是我的控制器

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

这是我的模型国家

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

这是我的模型城市

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

这是我的模型商店

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

这是我的看法

        <table class="table-fixed">
                <thead>
                  <tr>
                    <th class="py-2 px-2 border border-gray-300">Country</th>
                    <th class="py-2 px-2 border border-gray-300">City</th>
                    <th class="py-2 px-2 border border-gray-300">Shop</th>
                  </tr>
                </thead>
                <tbody>
                @foreach ($countries as $country)
                <tr >
                    <td class="py-2 px-2 border border-gray-300">{{ $country->name }}</td>
                    <td class="py-2 px-2 border border-gray-300">{{ $country->cities->count() }}</td>
                    <td class="py-2 px-2 border border-gray-300"></td>
                  </tr>
                @endforeach
                </tbody>
              </table>

我试过这段代码,它工作正常 City 正在计数

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

输出,在此输出中我想显示 shopsemployee

的计数

但是当我尝试这段代码时它给了我一个错误

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

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

您可以尝试通过查询本身获取聚合

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]);
    }
}

然后您可以访问聚合值作为

//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

您可以使用 addSelect 方法实现此目的 使用子查询并传递闭包

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();