Search code examples
databaselaravelextend

Modify database for extended models


I have this situation:

I have a table for Person (called persons). A person has a Name, an ID and a type (natural or juridical). Then I have Organization, it of course is a juridical person that extends a Person and has specific fields like manager_id or employees. Then I have an Authority which is a special government Organization, so in the end is also a Person and also has special required fields like decree_number (the number and year of the decree that constituted the Authority).

Then I have my database, where I have a table called persons.

My question is: should I create a new table for organizations and then another one for authorities? If not, how should I store the new fields that are required for Authorities or Organizations but not for a Persons?

I am doing this in a Laravel project, I could have:

/* Person.php */
class Person extends Model {
}

/* Organization.php */    
class Organization extends Person {
    protected $table = 'persons';
}

/* Authority.php */    
class Authority extends Organization {
    protected $table = 'persons';
}

Solution

  • Yes create another table but do not repeat the data which persons already has, you can just use relationships for that.

    For instance, create a table called organizations which stores persons with organization level. The schema can be:

    | person_id (FK to persons.id) | manager_id | other_fields |
    

    Then another table for authorities which stores persons with authority level. The schema can be:

    | person_id (FK to persons.id) | decree_number | other_fields |
    

    Then in Laravel, just create a relationship, I'm assuming a one-to-one relationship here.

    // Person.php
    
    public function organizationProfile()
    {
        return $this->hasOne(Organization::class);
    }
    
    public function authorityProfile()
    {
        return $this->hasOne(Authority::class);
    }
    
    public function hasOrganization()
    {
        return $this->organizationProfile !== null;
    }
    
    public function hasAuthority()
    {
        return $this->authorityProfile !== null;
    }
    

    The design is like a Person can have profiles (which in your case is Organization and Authority). There could be other design but this is what I've thought of.

    In summary, since Organization and Authority are both Persons with just another attribute, we just created another table to hold those attributes but not to repeat the attributes which are already present in Person. We will make use of relationships to determine if a Person is just a Person, an Organization or an Authority.