自定义一对一、一对多(多态)关系的实现

当表type类型为int时,需要使用到多态关系,类似以下结构

posts
id - integer
name - string

users
id - integer
name - string

images
id - integer
url - string
type_id - integer
type - int

首先按官方文档定义关系

 Relation::morphMap([
        1 => Posts:class,
        0 => Users:class
]);

再images模型中定义

public static function booted()
    {
  Relation::morphMap([
        1 => Posts:class,
        0 => Users:class
]);
    }

public function imageable()
{
  return $this->morphTo(__FUNCTION__, 'type', 'type_id');
}
//该定义为了预加载with实现
public function getTypeAttribute($value)
{
  return [
        1 => Posts:class,
        0 => Users:class
][$value];
}

当然也可以按官方提供的定义App\Providers\AppServiceProvider类的 boot方法内(除非你的系统只有一个地方使用到0,1 type类型)

/**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
        Relation::morphMap([
            1 => Posts:class,
            0 => Users:class
        ]);
    }

当type类型是顺序的0,1,2…,切记不要按顺序定义数组,否则框架中会按索引数组映射关系。框架的映射逻辑如下(src/Illuminate/Database/Eloquent/Relations/Relation.php 446行):

 protected static function buildMorphMapFromModels(array $models = null)
    {
        if (is_null($models) || Arr::isAssoc($models)) {
            return $models;
        }

        return array_combine(array_map(function ($model) {
            return (new $model)->getTable();
        }, $models), $models);
    }

完成以上配置后就可以使用自定义多态模型的查询

Images::find(1))->imageable;Images::with(['imageable']))->take(10)->get();
Images::with(['imageable'=>function (MorphTo $morphTo) {
    $morphTo->constrain( [
        Posts::class => function (Builder $query) {
            $query->select(['id',...]);
        },
        Users::class => function (Builder $query) {
            $query->select('id',...);
        },])
        ->morphWith([
        Posts::class => ['xxx:id,title'],
    ])])->whereHasMorph('imageable',[Posts::class])->take(10)->get();
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!