Database - rainistiirik23/Organization-api-exercise GitHub Wiki

Database structure

Since an organization may have multiple parents and multiple daughters, we'll have two tables: a organization table that has all the organizations and an organization relationships table with two columns: a daughter id and a parent id.This way it will be known which organization is the parent and which is the daughter in the relationship.

To also avoid duplicate entries, parent id and daughter id in combination will be unique.

        $table->foreignIdFor(Organization::class, 'parent_id')->constrained('organizations', 'id')->onDelete('cascade');
        $table->foreignIdFor(Organization::class, 'daughter_id')->constrained('organizations', 'id')->onDelete('cascade');
        $table->unique(['parent_id', 'daughter_id']);

Seeding the database

Organizations

Since the goal is to also have pagination for the results when retrieving organization's relationships, populating the table with that kind of data would be best to do with laravel's seeder class.

For organization seeder we'll be using a model factory for easier data population with unique values since every organization value is unique.

public function definition(): array
{
    return ['name' => fake()->unique()->company()];
}

Organization relationships

Organization relationship seeder however won't be using a factory, since a pair of foreign keys in organization_relationships table is unique a factory would give a constraint violation error.

public function run(): void
{
    $OrganizationRelationshipCreationCount = 1000;
    $insertedOrganizationRelationships = [];
    for ($i = 0; $i <= $OrganizationRelationshipCreationCount; $i++) {
        $parentId   = Organization::inRandomOrder()->first()->id;
        $daughterId = Organization::inRandomOrder()->first()->id;
        if ($daughterId == $parentId) {
            continue;
        }
        $insertedOrganizationRelationshipsCount = count($insertedOrganizationRelationships);
        for ($j = 0; $j < $insertedOrganizationRelationshipsCount; $j++) {
            if ($insertedOrganizationRelationships[$j]['parent_id'] == $parentId and $insertedOrganizationRelationships[$j]['daughter_id'] == $daughterId) {
                continue 2;
            }
        }
        $insertedOrganizationRelationships[] = ['parent_id' => $parentId, 'daughter_id' => $daughterId];
        OrganizationRelationship::create([
            'parent_id'   => $parentId,
            'daughter_id' => $daughterId,
        ]);
    }
}