Подсчитайте отдаленно связанные объекты в Laravel - PullRequest
0 голосов
/ 10 января 2019

Предположим, у вас есть три модели Eloquent в Laravel:

Person
 - id
 - name

Object
 - id
 - category_id
 - name

Category
 - id
 - name

Существует соотношение «многие ко многим» между Person и Object (один Person может принадлежать многим Objects, а один Object может принадлежать многим People), и существует множество одно отношение между Object и Category (многие Objects принадлежат одному Category).

Чтобы получить число Objects для Person, вы должны сделать что-то вроде

$ Person::withCount('objects')->first()

=> App\Person {
     id: 1,
     name: 'John Doe',
     objects_count: 5,
  }

То, что я хотел бы иметь, это число Objects на Category для каждого Person, при этом все еще имеется Person сущностей.

Я не уверен, если Eloquent сделает (или должен) сделать это в одном операторе БД, поскольку обычно with() приводит к одному дополнительному оператору для всех сущностей, с предложением where вроде WHERE id IN (1, 2, 3, ...).

Если бы мне пришлось обходиться без Person сущностей, я мог бы выполнить одну инструкцию SQL, которая дает необходимые результаты:

DB::table('person_object')
  ->join('objects', 'person_object.object_id', '=', 'objects.id')
  ->select(
      'person_id',
      'opjects.category_id', 
      DB::raw('count(*) as total')
  )
  ->groupBy('person_id', 'objects.category_id')
  ->get();

Это дает мне коллекцию, которую я, вероятно, смогу переназначить на Person идентификаторы:

=> Illuminate\Support\Collection {
     all: [
       {
         +"person_id": 1,
         +"category_id": 1,
         +"total": 2,
       },
       {
         +"person_id": 1,
         +"category_id": 2,
         +"total": 3,
       },
     ],
   }

Есть ли какой-нибудь более изящный способ, которым я сейчас скучаю?

...