Yogesh
Yogesh

Reputation: 41

Laravel Eloquent Many to Many Relationship between three Models

Consider I have the following table structures for tables countries, products and suppliers:

countries
------------------------
id
name
code
product
------------------------
id
name
price
suppliers
------------------------
id
name

A product can be sold in different countries but supplier of that product can be different. With that keeping in mind, I made a relations table to keep track of which supplier is delivering which product in which country:

relations
------------------------
country_id
product_id
supplier_id

Let's say I have a product A which I need to store in country US and CA but the suppliers for these countries are X and Y respectively. The structure would look something like this:

countries
-------------------------------
id    | name            | code
-------------------------------
1     | United States   | US
2     | Canada          | CA
product
-------------------------------
id    | name            | price
-------------------------------
1     | A               | 3.99
suppliers
------------
id    | name
------------
1     | X
2     | Y
relations
-------------------------------
country_id | product_id | supplier_id
-------------------------------
1          | 1          | 1
2          | 1          | 2

My question is how can I use Eloquent Relationships to this table since many-to-many relationships only work on two tables. Is there any other workaround regarding this? Or is there any other efficient way to implement this scenario?

Thank you for your help.

Upvotes: 4

Views: 1159

Answers (3)

Yogesh
Yogesh

Reputation: 41

As Jerodev suggested, I made an intermediate model SupplierProduct. Instead of making many-to-many relationships, I made one-to-many relationships with SupplierProduct and retrieved data using with functions to retrieve all data related to that record.

This is how my Models look like (database structure is same as described in question):

SupplierProduct.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class SupplierProduct extends Model {

    public function country() {
        return $this->belongsTo(Country::class);
    }

    public function product() {
        return $this->belongsTo(Product::class);
    }

    public function supplier() {
        return $this->belongsTo(Supplier::class);
    }

}

Country.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Country extends Model {
    public function products() {
        return $this->hasMany(SupplierProduct::class)->with('product', 'supplier');
    }
}

Product.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model {
    public function products() {
        return $this->hasMany(SupplierProduct::class)->with('country', 'supplier');
    }
}

Supplier.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Supplier extends Model {
    public function products() {
        return $this->hasMany(SupplierProduct::class)->with('country', 'product');
    }
}

Upvotes: 0

Khusal Berva
Khusal Berva

Reputation: 134

i have also same scenario class have multiple DaysClassDetails use this function in your parent model

public function classType()
{
    return $this->hasMany('App\DaysClassDetails(middlemodel)');
}  

and DaysClassDetails have multiple DaysClassTimeDetails

public function classTime()
{
    return $this->hasMany('App\DaysClassTimeDetails(lastchildmodel)');
}

public function classType(){
    return $this->belongsTo('App\ManageClass(parentmodel)');
}

Upvotes: 0

Jerodev
Jerodev

Reputation: 33186

There is no built-in way to make a relation using three tables. Whenever I encounter something like this myself, the best solution seems to be to make an in-between model that has relations to the three tables.

So in your case, I would create a SupplierProduct that has the relations country, supplier and product.

Upvotes: 2

Related Questions