stevema / laravel-relations
laravel的模型关系管理 项目中一堆模型的关系 管理起来很不舒服 写个插件专门做关系管理
v1.0.0
2023-11-15 15:56 UTC
This package is not auto-updated.
Last update: 2025-01-08 21:03:31 UTC
README
介绍
laravel的模型关系管理 项目中一堆模型的关系 管理起来很不舒服 写个插件专门做关系管理
软件架构
软件架构说明
安装教程
# 安装
$ composer require stevema/laravel-relations
使用说明
# 1、生成配置文件
$ php artisan vendor:publish --tag="relations"
# 2、修改配置文件 /config/relations.php
return [
/*
|--------------------------------------------------------------------------
| Relations Config
|--------------------------------------------------------------------------
|
| 直接把关系文件放到下面的数组中就行
|
*/
// 模型的别名 - 多态关系也会使用到模型的别名
'alias' => [
// '别名' => 模型::class,
],
// 模型的主键 没有特殊可以不定义 默认就是id
'primarys' => [
// '别名/模型:class' => '主键'
],
'relations' => [
],
];
目录说明
├─ src
│ ├─ Config # 配置文件目录
│ │ └─ config.php # 配置文件
│ ├─ Consoles # 命令行目录
│ │ └─ Commands # 命令文件目录
│ │ └─ Stubs # 生成文件模板目录
│ ├─ Traits # 引用文件
│ │ └─ MorphClassName.php # 模型引用它 可以控制关系别名
│ └─ ManyToMany.php # 多对多关系
│ └─ MorphManyToMany.php # 多态多对多关系
│ └─ MorphOneToMany.php # 多态一对多关系
│ └─ MorphOneToOne.php # 多态一对一关系
│ └─ OneToMany.php # 一对多关系
│ └─ OneToManyThrough.php # 远程一对多关系
│ └─ OneToOne.php # 一对一关系
│ └─ OneToOneThrough.php # 远程一对一关系
│ └─ Relations.php # 关系总管理
│ └─ RelationsProvider.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="relations"
# 3、修改配置文件 /config/relations.php 先加别名
return [
/*
|--------------------------------------------------------------------------
| Relations Config
|--------------------------------------------------------------------------
|
| 直接把关系文件放到下面的数组中就行
|
*/
// 模型的别名 - 多态关系也会使用到模型的别名
'alias' => [
// '别名' => 模型::class,
'badge' => \App\Models\api\Badge::class,
'user' => \App\Models\User::class,
'post' => \App\Models\api\Post::class,
'tag' => \App\Models\api\Tag::class,
'file' => \App\Models\api\File::class,
'category' => \App\Models\api\Category::class,
],
// 模型的主键 没有特殊可以不定义 默认就是id
'primarys' => [
// '别名/模型:class' => '主键'
],
'relations' => [
],
];
# 4、 执行命令 生成关系模型 UserProfile
$ php artisan make:relation UserProfile
请选择您的关系类型? [OneToOne[一对一]]:
[0] OneToOne[一对一]
[1] OneToMany[一对多]
[2] ManyToMany[多对多]
[3] OneToOneThrough[远程一对一]
[4] OneToManyThrough[远程一对多]
[5] MorphOneToOne[多态一对一]
[6] MorphOneToMany[多态一对多]
[7] MorphManyToMany[多态多对多]
# 选择一个后 生成 app/Relations/UserProfile.php 模型 根据注释来修改一下
# 里面的别名\模型:class 尽量用别名
# 生成表的时候如果不写别名没有class的情况下会输出错误信息
# 别名可以跳过相关的检测 生成表后 创建模型后可以修改相关配置
# 5.执行命令 生成migrate文件 (如果已经有了表 可以直接进入第8步)
$ php artisan relation:table
请选择一个关系 [App\Relations\UserProfile]:
[0] App\Relations\UserProfile
[1] App\Relations\UserPosts
[2] App\Relations\UserCollectPosts
[3] App\Relations\Likes
# 选择后会生成创建表文件 database/migrations/2023_08_24_000001_create_user_profiles_table.php
# 6.修改database/migrations下的文件 根据自己的需求添加字段 (如果已经有了表 可以直接进入第8步)
# 7、生成表 (如果已经有了表 可以直接进入第8步)
$ php artisan migrate
# 8、生成相关模型
$ php artisan make:model UserProfile
# 9.生成模型后 再去修改配置文件 添加别名和 relations中添加关系模型
return [
/*
|--------------------------------------------------------------------------
| Relations Config
|--------------------------------------------------------------------------
|
| 直接把关系文件放到下面的数组中就行
|
*/
// 模型的别名 - 多态关系也会使用到模型的别名
'alias' => [
// '别名' => 模型::class,
'badge' => \App\Models\api\Badge::class,
'user' => \App\Models\User::class,
'post' => \App\Models\api\Post::class,
'tag' => \App\Models\api\Tag::class,
'file' => \App\Models\api\File::class,
'category' => \App\Models\api\Category::class,
'user_profile' => \App\Models\api\UserProfile::class,
],
// 模型的主键 没有特殊可以不定义 默认就是id
'primarys' => [
// '别名/模型:class' => '主键'
],
'relations' => [
\App\Relations\UserProfile::class,
],
];
# 10. 现在关系生效了 可以去查看效果了
Route::get('t', function(){
$user = \App\Models\User::find(6);
dd($user->profile);
// profile 是 \App\Relations\UserProfile 中配置的
});
# 11. 查看所有模型绑定的关系
$ php artisan relation:list
+----------------------------+---------------+--------------------+------------+---------------+
| 模型 | 关联方法 | 关系名称 | 类型 | 角色 |
+----------------------------+---------------+--------------------+------------+---------------+
| App\Models\api\UserProfile | user | user_profile | 一对一 | belongsTo |
| App\Models\User | profile | user_profile | 一对一 | hasOne |
| App\Models\User | post | user_posts | 一对多 | hasMany |
| App\Models\User | collect_posts | user_post_collects | 多对多 | belongsToMany |
| App\Models\User | like_posts | likes | 多态多对多 | morphedByMany |
| App\Models\User | like_comments | likes | 多态多对多 | morphedByMany |
| App\Models\User | likes | likes | 多态多对多 | morphToMany |
| App\Models\User | like_users | likes | 多态多对多 | morphedByMany |
| App\Models\api\Post | user | user_posts | 一对多 | belongsTo |
| App\Models\api\Post | collect_users | user_post_collects | 多对多 | belongsToMany |
| App\Models\api\Post | likes | likes | 多态多对多 | morphToMany |
| App\Models\api\Comment | likes | likes | 多态多对多 | morphToMany |
+----------------------------+---------------+--------------------+------------+---------------+
# 12. 查看所有模型绑定的相关方法
$ php artisan relation:use [-a]
# -a 是全部 没有-a 会让你选择一个关系模型
您选择的是App\Relations\UserProfile
App\Models\api\UserProfile
// OneToOne[一对一] user_profile
public function user(){
return $this->belongsTo('App\Models\User', 'user_id', 'id')->withDefault();
}
App\Models\User
// OneToOne[一对一] user_profile
public function profile(){
return $this->hasOne('App\Models\api\UserProfile', 'user_id', 'id')->withDefault();
}
把这些方法拷贝到相应的模型中 就可以从配置文件 /config/relations.php 中删除了
备注
- 远程一对多关系 和 远程一对一关系 是一样的配置 一般远程一对一好像用不到吧
- 如果使用 php artisan relation:use 拷贝到对应的模型中 请务必删除配置文件[/config/relations.php]中的关系模型[relations 里面的] 多次绑定可能除了问题找不到原因
- 当 belongsTo,hasOne,hasOneThrough 和 morphOne 这些关联方法返回 null 的时候 你可以定义一个默认的模型返回。该模式通常被称为 空对象模式,它可以帮你省略代码中的一些条件判断。目前只支持 true false null array 还没支持闭包函数 有需要可以拷贝出来自定义