Laravel - полиморфные отношения «многие ко многим» - PullRequest
0 голосов
/ 18 октября 2018

Я бьюсь головой об определении полиморфных отношений в Laravel 5.7

Вот ситуация с данными: у меня есть модель для пользователей, модель для продуктов и модель для мерчендайзинга. Я в основном хочу построитьWishList для моего пользователя, который может содержать как товары, так и товары, и я хочу, чтобы там были полиморфные отношения, потому что мне придется добавлять новые типы вещей для продажи в более позднее время.

В моем (упрощенно)текущая схема данных, у меня есть

users
-email
-id

products
-id
-name

merchandises
-id
-name

И печально известная

wish_list_items
-user_id
-wish_list_item_type
-wish_list_id

С точки зрения отношений (на пользователя):

public function wishListProducts()
{
    return $this->morphedByMany(Product::class, 'wish_list_items');
}

public function wishListMerchandises()
{
    return $this->morphedByMany(Merchandise::class, 'wish_list_items');
}

Теперь это работает отлично,Но этого недостаточно для того, чего я хочу достичь - мне не хватает шага для получения ВСЕХ предметов в Списке желаний, независимо от их типа.На данный момент:

public function wishListAll()
{
    return $this->load(['wishListProducts','wishListMerchandises']);
}

Что, очевидно, дает мне список всего, но в отдельных коллекциях - и я хочу единый.

Первый вопрос, есть ли способ получить всесвязан с этим пользователем, независимо от типа?Это может быть довольно просто, но я нигде не могу его найти.

Если это невозможно (что я на самом деле подозреваю - но это будет означать, что эти полиморфные отношения являются не чем иным, как способом избежать создания другой сводной таблицы, что я не против сделать), что делают людидумаете, будет ли лучший способ продолжить?Первоначальная идея состояла в том, чтобы создать интерфейс, который будут реализованы во всей моей модели sellables, чтобы объединить все - хотя мне все равно придется просматривать все мои отдельные коллекции, если только нет простого способа объединить их, поскольку они реализуют одно и то же.интерфейс?Или я должен просто определить модель для моих WishListItems (это сводная таблица на данный момент, поэтому модель не была определена), заставить все мои продаваемые модели расширять супер модель и попытаться связать отношения вместе?

Спасибо за ввод!

1 Ответ

0 голосов
/ 18 октября 2018

Решение по умолчанию - это средство доступа, объединяющее две (или более) коллекции:

public function getWishListItemsAttribute()
{
    return $this->wishListProducts->toBase()->merge($this->wishListMerchandises);
}

// $user->wishListItems

+++ UPDATE +++

Я создал пакет дляотношения слияния с использованием представлений:
https://github.com/staudenmeir/laravel-merged-relations

Сначала создайте представление слияния в миграции:

use Staudenmeir\LaravelMergedRelations\Facades\Schema;

Schema::createMergeView(
    'wish_list_items', [(new User)->wishListMerchandises(), (new User)->wishListProducts()]
);

Затем определите отношение:

class User extends Model
{
    use \Staudenmeir\LaravelMergedRelations\Eloquent\HasMergedRelationships;

    public function wishListItems()
    {
        return $this->mergedRelation('wish_list_items');
    }
}

Используйте это как любые другие отношения:

$user->wishListItems;

$user->wishListItems()->paginate();

User::with('wishListItems')->get();
...