Laravel - 多对多多态关联

4

我正在Laravel 5.7中努力理解多态关系的定义。

这是数据情况: 我有一个用户模型,一个产品模型和一个商品模型。 基本上,我想为我的用户构建一个愿望清单,其中可以包含Merchandises和Products,并且我想在那里使用多态关系,因为我将来可能需要添加新类型的销售物品。

在我的(简化后的)当前数据架构中,我有

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定义一个模型(它目前是一个数据透视表,因此尚未定义模型),使所有可销售模型扩展超级模型,并尝试将关系链接在一起?

感谢您的帮助!

1个回答

4
“默认”方案是一个访问器,它将两个(或更多)集合合并在一起:
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();

好的,这就解决了问题。现在如果我的模型实现了相同的接口,我就有一个统一的集合可以通过我的业务流程传递。非常感谢! - Ours
我已经创建了一个用于合并关系的包并将其添加到我的答案中。 - Jonas Staudenmeir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接