Laravel проверяет ценность отношения

У меня есть запрос, который выглядит примерно так, где я извлекаю данные для различных предприятий в определенном месте, и мне нужно иметь возможность сказать, что в каждом бизнесе есть (или нет) женщина-сотрудник.

    $business = Business::where('location', $location)
        ->with(['staff'])
        ->get();


        return MiniResource::collection($business);

Мой мини-ресурс выглядит так:

    return [
        'name' => $this->name,
        'location' => $this->location,
        'staff' => PersonResource::collection($this->whenLoaded('staff')),
    ];

Вот как выглядит образец ответа:

{
  "id": 1,
  "name": "XYZ Business"
  "location": "London",
  "staff": [
    {
      "name": "Abigail",
      "gender": "f",
      "image": "https://s3.amazonaws.com/xxxx/people/xxxx.png",
      "role": "Project Manager",
    },
    {
      "name": "Ben",
      "gender": "m",
      "image": "https://s3.amazonaws.com/xxxx/people/xxxx.png",
      "role": "Chef",
    },
  ]
}

Мне действительно не нужен массив персонала, я просто хочу проверить, существует ли женщина в отношении, а затем вернуть что-то похожее на это:

{
  "id": 1,
  "name": "XYZ Business"
  "country": "USA",
  "has_female_employee": true;
}

Есть ли красноречивый способ добиться этого?

NB: В моем исходном коде у меня есть больше отношений, которые я запрашиваю, но мне пришлось ограничить этот пост, чтобы он попадал в рамки моей проблемы.

2 ответа

Решение

Если вы ищете только сотрудников мужского или женского пола, вы можете добиться этого следующим образом:

$someQuery->whereHas('staff', function ($query) {
    $query->where('gender', 'f');
})

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

return [
    'name' => $this->name,
    'location' => $this->location,
    'has_female_employee' => $this->whenLoaded('staff')->reduce(
        function ($hasFemale, $employee) {
            $hasFemale = $hasFemale || ($employee->gender === 'f'); 
            return $hasFemale;
        }, false),
];

Еще лучше было бы создать его как метод в вашем MiniResource для удобства чтения.

Измените свой код, как показано ниже, и посмотрите

$business = Business::where('location', $location)
        ->with(['staff'])
        ->where('gender', 'f')
        ->get();
return [
        'name' => $this->name,
        'location' => $this->location,
        'has_female_employee' => empty($this->whenLoaded('staff')) ? false : true,
    ];
Другие вопросы по тегам