本小节,介绍一下 laravel 中的多态关联。其实,就是总结一下使用的经验,刚刚在网上查了一下,很多博客没有讲全,而且看上去基本上内容差不多,比如,如何新增中间表数据,就很少有文章说到。

    多态解决的问题

        很多业务场景,经常共用到一张表,以前我们会用冗余字段来分别标识,或者用一个 type 来区分。其实多态的概念跟利用 type 区分含义差不多,唯一不同的就是,利用多态关系 Laravel 自动帮我们把底层关系处理好了。

    场景举例

        用户所有的资金流动都会被记录到流水表 stream 中。不同的应用又会有相对应的表。比如,用户订单表和抢红包表,等等这些业务都会将对应的金额插入到 stream 中。

    表结构
--- 订单表 order
-- id
-- money
-- order_num
--...

--- 红包表 redpack
-- id
-- money
-- ...

--- 流水表 stream
-- id
-- streamable_id
-- streamable_type
-- ...

stream 表通过 streamable_type 记录不同模型,来分别和对应模型的表关联。streamable_id 则是对应模型的 id。

    模型结构
// Order.php
...
use App\Stream;
...
public function streams()
{
return $this->morthMany(Stream::class, 'streamable');
}

// RedPack.php
...
use App\Stream;
...
public function streams()
{
return $this->morthMany(Stream::class, 'streamable');
}

// Stream.php
...
use App\Stream;
...
public function streamable()
{
return $this->morphTo(Stream::class, 'stream');
}

知道模型的小伙伴,就知道这里的关键方法 morphTo 和 morthMany 是定义多态的。

    基本使用
// 新增方式一:根据已存在的模型查询
...
use App\Order;
use App\Stream;
...
$order = Order::query()->find(1); // 查询 id 为1的order
$stream = new Stream([
// 这里可以填写 stream 表的额外字段。streamable_id 和 streamable_type 模型自动识别插入
]);
$order->stream()->save($stream);
// 新增方式二:新增时同时插入多态表
Order::create([])->stream()->save(new Stream([]));

// 查询
$orderData = Order::query()->with('streams')->find(1);
$orderData->stream->toArray();

上面,就是对多态关联的一些简单的使用。

由于能力有限,不足或有不解之处,希望在下方评论区与我讨论,共同提高 。