问题
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