Отношения многих ко многим в Laravel между тремя моделями

Предположим, у меня есть следующие структуры таблиц для таблиц countries, products и suppliers:

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

product может быть продан в разных countries, но supplier из этого product может быть другим. Помня об этом, я составил relations таблицу, чтобы отслеживать, какие supplier доставляют, какие product в каких country:

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

Допустим, у меня есть продукт A, который мне нужно хранить в стране US и CA, но поставщиками для этих стран являются X и Y соответственно. Структура будет выглядеть примерно так:

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

У меня вопрос, как я могу использовать красноречивые отношения для этой таблицы, поскольку отношения «многие ко многим» работают только с двумя таблицами. Есть ли другой способ решения этой проблемы? Или есть другой эффективный способ реализовать этот сценарий?

Спасибо за помощь.


person Yogesh    schedule 03.12.2019    source источник


Ответы (3)


Не существует встроенного способа установить связь с использованием трех таблиц. Когда я сам сталкиваюсь с чем-то подобным, лучшим решением будет создание промежуточной модели, имеющей отношение к трем таблицам.

Итак, в вашем случае я бы создал SupplierProduct, который имеет отношения country, supplier и product.

person Jerodev    schedule 03.12.2019

У меня также есть тот же класс сценария, у которого несколько DaysClassDetails, используйте эту функцию в вашей родительской модели

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

и DaysClassDetails имеют несколько DaysClassTimeDetails

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

public function classType(){
    return $this->belongsTo('App\ManageClass(parentmodel)');
}
person Khusal Berva    schedule 03.12.2019

Как предложил Джеродев , я создал промежуточную модель SupplierProduct. Вместо того, чтобы создавать отношения «многие ко многим», я установил отношения «один ко многим» с SupplierProduct и извлекал данные с помощью функций with для извлечения всех данных, связанных с этой записью.

Вот как выглядят мои модели (структура базы данных такая же, как описано в вопросе):

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');
    }
}
person Yogesh    schedule 06.12.2019