Search code examples
laraveleloquentlaravel-8eloquent-relationship

How to relate three tables in laravel


I am trying to develop a p2p app in laravel.

I have three tables in my database namely users, loans, and installments.

Now, users and loans can have multiple installments and each installment will belong to a user and a loan.

So how do I define this relationship? Do I need a polymorphic relationship? If so, how do relate a user and a loan to a single installment?


Solution

  • each installment will belong to a user and a loan.

    That pretty much answers the question.

    If your requirement was "each installment will belong to either an user or a loan", then the relationship would be polymorphic.

    Minimal table structure

    Schema::create('users', function (Blueprint $table) {
        $table->bigIncrements('id');
        ... // other users fields or indexes.
    });
    
    Schema::create('loans', function (Blueprint $table) {
        $table->bigIncrements('id');
        ... // other loans fields or indexes.
    });
    
    Schema::create('installments', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->foreignId('user_id')->constrained('users');
        $table->foreignId('loan_id')->constrained('loans');
        ... // other installments fields or indexes.
    });
    

    IF an Installment's user_id or loan_id can be null, add ->nullable() before ->constrained(). For example:

    Schema::create('installments', function (Blueprint $table) {
        ...
        $table->foreignId('user_id')->nullable()->constrained('users');
        ...
    });
    

    IF you can't have more than one installment associated with the same user/loan pair, add a unique index.

    Schema::create('installments', function (Blueprint $table) {
        ...
        $table->unique(['user_id', 'loan_id']);
        ...
    });
    

    Relationships to define

    User model:

    • public function installments() { return $this->hasMany(Installment::class); }
    • public function loans() { return $this->belongsToMany(Loan::class, 'installments'); }

    Loan model:

    • public function installments() { return $this->hasMany(Installment::class); }
    • public function users() { return $this->belongsToMany(User::class, 'installments'); }

    Installment model:

    • public function loan() { return $this->belongsTo(Loan::class); }
    • public function user() { return $this->belongsTo(User::class); }

    https://laravel.com/docs/eloquent-relationships#inserting-and-updating-related-models

    https://laravel.com/docs/eloquent-relationships#syncing-associations

    https://laravel.com/docs/eloquent-relationships#updating-a-record-on-the-intermediate-table

    syncWithoutDetaching() and updateExistingPivot() are particularly important methods if you have a unique constraint.