I have five tables: requesters, document types, protocols, flows and documents.
Relationships
- Requester has many document types.
- Requester has many protocols.
- Protocol has many flows.
- Flow has many documents.
- Document type has many documents.
Problem
Select all protocols that have the first flow (let's say sequence = 1) with documents having all document types for protocol requester.
In other words, select the protocols that doesn't have pendencies, this means protocols with documents inside first flow having all required document types for protocol requester.
Solution
I ended up with a solution that actually doesn't work because I can't access requester_id value inside protocols whereHas Closure:
// All document types id's group by requester id's.
$documentTypesByRequester = DocumentType::all()
->groupBy('requester_id')
->map(function ($documentTypes, $requesterId) {
return $documentTypes->pluck('id')
->toArray();
})->toArray();
// Defined statically to reduce the complexity of question.
// $documentTypesByRequester = [
// 1 => [1, 2, 3],
// 2 => [4, 5]
// ];
// Here I have to select all protocols that have flows with
// documents having all document types of protocol requester.
$protocols = Protocol::whereHas('flows', function ($flows) use ($documentTypesByRequester) {
//
// *---------------------------------------
// * THIS DOESN'T WORK BUT IS WHAT I NEED!
// *---------------------------------------
//
// Access the requester id for current protocol.
$requesterId = $flows->first()
->protocol
->requester_id;
$documentTypesId = $documentTypesByRequester[$requesterId];
return $flows->where('sequence', 1)
->whereHas('documents', function ($documents) use ($documentTypesId) {
return $documents->whereIn('document_type_id', $documentTypesId);
}, '=', count($documentTypesId));
})->get();
There is some way to access values of model inside this whereHas Closure or exists another alternative to help me solve this query?
documentTypesByRequesterstatically? I want to give this query a try, but with static data it's a bit tricky and I might unnecessarily over-complicate stuff.