Organizations - rainistiirik23/Organization-api-exercise GitHub Wiki
Inserting organization
First part comes with getting the name of the organization from the request and inserting it into the database, the more complicated part comes with inserting daughter organizations.
An organization may have many daughter and parent organizations and those organizations may even have their own daughter organizations, this part will be in its own method.
$this->insertDaughterParentOrganizations($daughterOrganizations, $parentId);
Each daughter organization will be inserted through a for loop with elequent's firstOrCreate method so we don't insert duplicate records.
$daughterOrganizations = [];
for ($i = 0; $i < count($organizations); $i++) {
Organization::firstOrCreate(['name' => $organizations[$i]['org_name']]);
$daughterOrganizations[] = ['name' => $organizations[$i]['org_name']];
}
Another reason why this is in another method is because it needs to call itself.
for ($i = 0; $i < count($organizations); $i++) {
if (array_key_exists('daughters', $organizations[$i]) && count($organizations[$i]['daughters'])) {
$parentOrganization = Organization::where('name', $organizations[$i]['org_name'])->get();
$this->insertDaughterParentOrganizations($organizations[$i]['daughters'], $parentOrganization[0]->id);
}
}
Retrieve related organizations
Organization's daughter and parent organizations will be retrieved through the defined relationships within the organization model.
public function parents(): BelongsToMany
{
return $this->BelongsToMany(Organization::class, 'organization_relationships', 'daughter_id', 'parent_id',);
}
public function daughters(): BelongsToMany
{
return $this->BelongsToMany(Organization::class, 'oganization_relationships', 'parent_id', 'daughter_id');
}
With these methods we'll get the id values of the organizations.
Having all the id values will more easily make it easier to order all the organizations by name and limit how many are shown with pagination.
Pagination
Pagination will be done by invoking the method on the collection.
$sortedParentDaughterSisterOrganizationsWithRelationTypes = collect($parentDaughterSisterOrganizationsWithRelationTypes)->sortBy('name')->values()->paginate(100);
However the pagination does not exist for the collection, to get around this we'll make a collection macro with the pagination logic in the AppServiceProvider.
public function boot(): void
{
Collection::macro('paginate', function ($perPage, $total = null, $page = null, $pageName = 'page'): LengthAwarePaginator {
$page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
return new LengthAwarePaginator(
$this->forPage($page, $perPage)->values(),
$total ?: $this->count(),
$perPage,
$page,
[
'path' => LengthAwarePaginator::resolveCurrentPath(),
'pageName' => $pageName,
]
);
});
}