stevema / laravel-morphmap
laravel的别名配置-多态关系动态添加不用自己写服务提供者了,配置文件中定义一下就行
v1.0.0
2023-08-31 14:59 UTC
This package is not auto-updated.
Last update: 2025-01-02 21:20:08 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 | [多态一对多]查看我的评论关系 | 否 |
+------------------------+---------------+----------------------------------------+----------+
备注
没有什么备注了-这就是全部了-以后想到什么再加吧