Laravel - Many-to-Many polymorphic relationships

﹥>﹥吖頭↗ 提交于 2020-01-02 08:48:48

问题


I'm banging my head against a polymorphic relationship definition within Laravel 5.7

Here's the data situation: I have a model for Users, a model for Products and a model for Merchandising I basically want to build a WishList for my user, that can contain both Merchandises and Products, and I want to have a polymorphic relationship there because I will have to add new types of things to sell at a later time.

In my (simplified) current data schema, I have

users
-email
-id

products
-id
-name

merchandises
-id
-name

And the infamous one

wish_list_items
-user_id
-wish_list_item_type
-wish_list_id

In terms of relationships (on User):

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

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

Now this working great. But it is not enough for what I want to achieve - what I am missing is the step to fetch ALL the items of the Wish List, regardless of their type. At the moment:

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

Which obviously give me a list of everything, but in separated collections - and I want a unified one.

First question, is there a way to get everything associated to that user, regardless of the type? It might be pretty simple but I can't find it anywhere.

If it's not possible (which I actually suspect - but that would mean that those polymorphic relationships are not much more than a way to avoid creating another pivot table, which I wouldn't mind doing), what do people think would be the best way to proceed? The starting idea was to create an interface, which all my sellables model would implement, in order to unify everything - I'd still have to loop through all my seperated collections though, unless there's an easy way to merge them as they implement the same interface? Or should I just define a model for my WishListItems (it's a pivot table at the moment, so the model hasn't been defined), make all my sellables models extand the super model, and try to link relationships together?

Thanks for input!


回答1:


The "default" solution is an accessor that merges the two (or more) collections:

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

// $user->wishListItems

+++ UPDATE +++

I've created a package for merging relationships using views:
https://github.com/staudenmeir/laravel-merged-relations

First, create the merge view in a migration:

use Staudenmeir\LaravelMergedRelations\Facades\Schema;

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

Then define the relationship:

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

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

Use it like any other relationship:

$user->wishListItems;

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

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


来源:https://stackoverflow.com/questions/52877446/laravel-many-to-many-polymorphic-relationships

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!