stevema/laravel-morphmap

laravel的别名配置-多态关系动态添加不用自己写服务提供者了,配置文件中定义一下就行

v1.0.0 2023-08-31 14:59 UTC

This package is not auto-updated.

Last update: 2024-05-23 18:31:34 UTC


README

介绍

laravel的别名配置-多态关系动态添加 不用自己写服务提供者了,配置文件中定义一下就行 忽然感觉自己写的有点问题 - 目前只支持多态的关系 新写一个项目 https://gitee.com/steve_ma/laravel-relations

安装教程


# 安装

$ composer require stevema/laravel-morphmap

使用说明

# 1、生成配置文件
$ php artisan vendor:publish --tag="morphmap"

# 2、修改配置文件 /config/morphmap.php
<?php
use Stevema\MorphMap\MorphConfigResource;
return [
    // 关系别名 多态关系中 有个别名还是有些好处的
    'alias' => [
        // '别名' => 模型::class,
    ],
    // 主键关系  不定义或者null 主键就是id 所以可以不定义 没有特殊这个可以不定义
    'primarys' => [
        // '别名/模型:class' => '主键'
    ],

    // 关联关系 多态关系是需要关联表名的
    'morphs' => [
        
    ],
];

目录说明

├─ src
│   ├─ Config           # 配置文件目录
│   │   └─ config.php   # 配置文件
│   ├─ Consoles         # 命令行目录
│   │   └─ Commands     # 命令文件目录
│   │   └─ Stubs        # 生成文件模板目录
│   ├─ Traits           # 引用文件
│   │   └─ MorphClassName.php   # 模型引用它 可以控制关系别名
│   └─ MorphConfigResource.php  # 配置阅读器-解析出想要的配置信息
│   └─ MorphMapProvider.php  # 服务者-里面只做了config获取配置后自动注册别名
└─ composer.json        # 配置

MorphClassName 说明

use Illuminate\Database\Eloquent\Relations\Relation;
// 多态关联的时候 model use这个可以自定义 type 的 别名
trait MorphClassName
{
    // 配置多态的关联关系后 其中的able_type竟然是 App\Models\User 这种
    // 很长不说 还把我的命名空间给暴露了 - 不能忍
    
    // 没配置别名的话 使用表明当做别名
    public bool $useTableNameToMorphName = false;
    
    // 如果没配置别名还不想用表名的话 可以分割命名空间直到获取到模型名
    public bool $classBasename = True;
    
    // 模型都会有这个方法 我这里重写它 按我想要的规则去找别名
    public function getMorphClass()
    {   
        // 获取别名
        $morphMap = Relation::morphMap();
        // 查找别名 找到就返回
        if (! empty($morphMap) && in_array(static::class, $morphMap)) {
            return array_search(static::class, $morphMap, true);
        }
        // 输出表名
        if($this->useTableNameToMorphName){
            return $this->getTable();
        }
        // 输出类名 去掉命名空间后的
        if($this->classBasename){
            return class_basename(self::class);
        }
        // 最不能忍的就是这个输出带命名空间的类名
        return self::class;
    }
}

使用说明 - 从零开始使用

# 1安装

$ composer require stevema/laravel-morphmap

# 2、生成配置文件
$ php artisan vendor:publish --tag="morphmap"

# 2、修改配置文件 /config/morphmap.php
# 去掉那些配置后剩下的
<?php
use Stevema\MorphMap\MorphConfigResource;
return [
    // 关系别名 多态关系中 有个别名还是有些好处的
    'alias' => [
        // '别名' => 模型::class,
        'post' => \App\Models\api\Post::class,
    ],
    // 主键关系  不定义或者null 主键就是id 所以可以不定义 没有特殊这个可以不定义
    'primarys' => [
        // '别名/模型:class' => '主键'
    ],
    
    // 关联关系 多态关系是需要关联表名的
    'morphs' => [
        'images' => [
            // 关系表说明 多对多是中间表 一对一和一对多是主体表
            'comment' => '图片封面',
            // 关系 MorphConfigResource::MORPH_ONE2ONE[多态一对一]
            // 关系 MorphConfigResource::MORPH_ONE2MANY[多态一对多]
            // 关系 MorphConfigResource::MORPH_MANY2MANY[多态多对多]
            'type' => MorphConfigResource::MORPH_ONE2ONE,
            // 一对一 和 一对多 是需要相关的主体模型 多对多也需要但是主体有些不一样
            'model' => 'image', // 别名或者模型::class 
            // 主体在关系表中的字段名 多对多关系用到  为空则为 主体模型.主体模型的主键
            'primary_name' => null, // 'user_id'
            // 关联的ablename 为空则默认关系表名.'_able'
            'able_name' => null,
            // able_type_name 字段名 如果null 则自动根据able_name 生成 [$(able_name) . '_type']
            'able_type_name' => null,
            // able_id_name 字段名 如果null 则自动根据able_name 生成 [$(able_name) . '_id']
            'able_id_name' => null,
            // 主体中定义的的方法名  如果为空则为 able_name的值 多对多关系这个就不需要了
            'morphs_name' => null,
            // 关系中定义的方法名 为空则用关系表名
            'morph_name' => null,
            //关系列表 主体对应多个模型
            'morphs' => [
                // 别名或者模型:class  比如 Post::class 关联
                // '别名/模型:class' => '方法名',
                // 一对一 一对多 的情况下 方法名会绑定在关系模型中  null 则用 morph_name 覆盖
                // 多对多 的情况下 方法名会绑定在主体模型中 不能是null 关系模型绑定 morph_name 方法
                'post' => null, // 去掉 Post::class 外面的单引号
            ],
        ],
    ],
];

# 虽然我添加了 images 关系 关联了 post 
# 但是因为没有主体 这个时候这个关系是不生效的 
# 'model' => 'image' 这里虽然没有定义Image的模型别名
# 写上之后可以更准确的定义下一步表里的able

# 3、执行命令 生成migrate文件 (如果已经有了表 可以跳过这一步)
$ php artisan morph:table images

# 输出  INFO  migrate [database/migrations/2023_08_24_000001_create_images_table.php] created successfully.
# 生成migrate文件成功 可以去调整这个表 添加自己想要的字段或者修改

# 4、生成表
$ php artisan migrate

# 5、生成模型
$ php artisan make:model Image
# 6.生成模型后 再去修改配置文件

return [
    // 添加了post模型和image模型
    'alias' => [
        // '别名' => 模型::class,
        'post' => \App\Models\api\Post::class,
        'image' => \App\Models\Image::class,
    ],
    // 主键关系 如果你的主键不是id 就定义一下
    'primarys' => [
        // '别名/模型:class' => '主键'
        // 下面这俩行效果是一样的 因为主键是id 所以我注释了
//        \App\Models\Image::class => 'id',
//        'image' => 'id',
    ],
    
    // 关联关系 多态关系是需要关联表名的
    'morphs' => [
        'images' => [
            // 关系表说明 多对多是中间表 一对一和一对多是主体表
            'comment' => '图片封面',
            // 关系 one2one[一对一] one2many[一对多] many2many[多对多]
            'type' => 'one2one',
            // 一对一 和 一对多 是需要相关的主体模型 多对多也需要但是主体有些不一样
            'model' => 'image', // 别名或者模型::class 
            // 主体在关系表中的字段名 多对多关系用到  为空则为 主体模型.主体模型的主键
            'primary_name' => null, // 'user_id'
            // 关联的ablename 为空则默认关系表名.'_able'
            'able_name' => null,
            // able_type_name 字段名 如果null 则自动根据able_name 生成 [$(able_name) . '_type']
            'able_type_name' => null,
            // able_id_name 字段名 如果null 则自动根据able_name 生成 [$(able_name) . '_id']
            'able_id_name' => null,
            // 主体中定义的的方法名  如果为空则为 able_name的值 多对多关系这个就不需要了
            'morphs_name' => null,
            // 关系中定义的方法名 为空则用关系表名
            'morph_name' => null,
            //关系列表 主体对应多个模型
            'morphs' => [
                // 别名或者模型:class  比如 Post::class 关联
                // '别名/模型:class' => '方法名',
                // 一对一 一对多 的情况下 方法名会绑定在关系模型中  null 则用 morph_name 覆盖
                // 多对多 的情况下 方法名会绑定在主体模型中 不能是null 关系模型绑定 morph_name 方法
                'post' => null, // 去掉 Post::class 外面的单引号
            ],
        ],
    ],
];
# 'model' => 'image' 上面添加了别名 image现在有对应的模型了
# 或者这里改成 'model' => Image::class  也是一样的

# 7. 现在关系生效了 可以去查看效果了
Route::get('t', function(){
    $post = \App\Models\api\Post::with('images')->find(6);
    
    dd($post->images);
    // 一对一 是一个模型 一对多 是数组
    // 多对多是关系模型的数组
});
# 8. 查看所有模型绑定的关系
$ php artisan morph:list

+------------------------+---------------+----------------------------------------+----------+
| 模型                   | 关联方法      | 备注                                   | 关联主体 |
+------------------------+---------------+----------------------------------------+----------+
| App\Models\User        | badges        | [多态多对多]查看我的勋章关系           | 否       |
| App\Models\User        | like_posts    | [多态多对多]查看我和关联模型的点赞关系 | 是       |
| App\Models\User        | like_comments | [多态多对多]查看我和关联模型的点赞关系 | 是       |
| App\Models\User        | likes         | [多态多对多]查看我的点赞关系           | 否       |
| App\Models\User        | like_users    | [多态多对多]查看我和关联模型的点赞关系 | 是       |
| App\Models\api\Badge   | users         | [多态多对多]查看我和关联模型的勋章关系 | 是       |
| App\Models\api\Post    | likes         | [多态多对多]查看我的点赞关系           | 否       |
| App\Models\api\Post    | comments      | [多态一对多]查看我的评论关系           | 否       |
| App\Models\api\Comment | likes         | [多态多对多]查看我的点赞关系           | 否       |
| App\Models\api\Comment | comment_able  | [多态一对多]查看我的评论关系关联模型   | 是       |
| App\Models\api\Comment | comments      | [多态一对多]查看我的评论关系           | 否       |
+------------------------+---------------+----------------------------------------+----------+



备注

没有什么备注了-这就是全部了-以后想到什么再加吧