empu/eloquent-subtype

Your Package Description here

v0.1.0 2022-09-06 01:09 UTC

This package is auto-updated.

Last update: 2024-03-26 10:40:02 UTC


README

Supertype and Subtypes

At times, few entities in a data model may share some common properties (attributes) within themselves apart from having one or more distinct attributes. Based on the attributes, these entities are categorized as Supertype and Subtype entities.

Supertype is an entity type that has got relationship (parent to child relationship) with one or more subtypes and it contains attributes that are common to its subtypes. Subtypes re subgroups of the supertype entity and have unique attributes, but they will be different from each subtype.

Supertypes and Subtypes are parent and child entities respectively and the primary keys of supertype and subtype are always identical.

Case

                    +---------------+
                    |    Parties    |
                    +---------------+
                    | ssn           |
                    | name          |
                    | email         |
                    +---------------+
                           |
                           O
                           |
            --------------------------------------
           |                                      |
    +--------------+                    +------------------+
    |   Teachers   |                    |     Students     |
    +--------------+                    +------------------+
    | salary       |                    | major_department |
    | date_of_hire |                    +------------------+
    +--------------+

Here "Parties" is the supertype or parent entity whereas the child entities "Employees" and "Students" are subtypes.

How to install

Adding package to the project

This repository is valid composer package, but not registered yet on the packagist repository.

To install this package, add git@gitlab.com:empu/eloquent-subtype.git as a repository url and add empu/eloquent-subtype as a project dependency in your composer.json.

{
    "name": "laravel/laravel",
    "type": "project",
    "repositories" : [
        {
            "type": "vcs",
            "url": "git@gitlab.com:empu/eloquent-subtype.git"
        }
    ],
    // ... other settings
}

Run composer install empu/eloquent-subtype:dev-master from your terminal in the project root directory.

Preparing tables and models

To make eloquent-subtype working well, the entity tables and the models must follow several rules.

Supertype entity

Schema for parties the supertype table:

    Schema::create('parties', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('ssn')->unique();
        $table->string('name');
        $table->string('email')->unique()->nullable();
        $table->timestamps();
    });

The model of parties:

use Empu\EloquentSubtype\Contracts\InheritableEntity;
use Illuminate\Database\Eloquent\Model;

class Party extends Model implements InheritableEntity
{
    public function descendibleColumns(): array
    {
        return ['ssn', 'name', 'email'];
    }
}

Subtype entity

Schema for students the subtype table:

    Schema::create('students', function (Blueprint $table) {
        $table->foreignId('super_id')->constrained('parties');
        $table->primary('super_id');
        $table->string('major_department');
        $table->timestamps();
    });

The model of students:

use Empu\EloquentSubtype\Concerns\HasSupertype;
use Empu\EloquentSubtype\Contracts\InteractWithSupertype;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Student extends Model implements InteractWithSupertype
{
    use HasSupertype;

    protected $supertype = 'party';

    public function party(): BelongsTo
    {
        return $this->belongsTo(Party::class);
    }
}

Subtype in action

$student = App\Models\Student::make();
$student->ssn = 112233;
$student->name = 'Aqlan';
$student->email = 'aqlan@example.com';
$student->major_department = 'Tarbia';
$student->save();

dump(App\Models\Student::all());
// Illuminate\Database\Eloquent\Collection {#3925
//     all: [
//         App\Models\Student {#4285
//             super_id: 2,
//             major_department: "Tarbia",
//             created_at: "2022-09-06 00:47:07",
//             updated_at: "2022-09-06 00:47:07",
//             id: 2,
//             ssn: "112233",
//             name: "Aqlan",
//             email: "aqlan@example.com",
//         },
//     ],
// }
dump(App\Models\Party::all());
// Illuminate\Database\Eloquent\Collection {#4534
//     all: [
//         App\Models\Party {#4540
//             id: 2,
//             ssn: "112233",
//             name: "Aqlan",
//             email: "aqlan@example.com",
//             created_at: "2022-09-06 00:47:07",
//             updated_at: "2022-09-06 00:47:07",
//         },
//     ],
// }

TODO

[] create subtype entity from existing supertype [] command to generate proper migrations [] readme need to be tidy up, write documentation is hard