Я бьюсь головой о определение полиморфных отношений в 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']);
}
Которые, очевидно, дают мне список всего, но в отдельных коллекциях - а я хочу единую.
Первый вопрос: есть ли способ получить все, что связано с этим пользователем, независимо от типа? Это может быть довольно просто, но я нигде не могу его найти.
Если это невозможно (что я действительно подозреваю, но это будет означать, что эти полиморфные отношения - не более чем способ избежать создания еще одной сводной таблицы, что я бы не прочь сделать), то что люди думают, было бы лучшим способом? продолжать? Первоначальной идеей было создать интерфейс, который будет реализовывать вся моя продаваемая модель, чтобы все унифицировать - мне все равно придется перебирать все мои отдельные коллекции, если нет простого способа объединить их, поскольку они реализуют то же самое. интерфейс? Или я должен просто определить модель для моих WishListItems (на данный момент это сводная таблица, поэтому модель не определена), сделать так, чтобы все мои продаваемые модели расширяли супермодель, и попытаться связать отношения вместе?
Спасибо за вклад!





Решение "по умолчанию" - это средство доступа, которое объединяет две (или более) коллекции:
public function getWishListItemsAttribute()
{
return $this->wishListProducts->toBase()->merge($this->wishListMerchandises);
}
// $user->wishListItems
+++ ОБНОВЛЕНИЕ +++
Я создал пакет для объединения отношений с использованием представлений:
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();
Я создал пакет для объединения отношений и добавил его в свой ответ.
Что ж, это помогло. Теперь, если мои модели реализуют один и тот же интерфейс, у меня есть унифицированная коллекция, которую я могу передать через свои бизнес-процессы. Большое спасибо!