# laravel-relations **Repository Path**: steve_ma/laravel-relations ## Basic Information - **Project Name**: laravel-relations - **Description**: laravel的模型关系管理 项目中一堆模型的关系 管理起来很不舒服 写个插件专门做关系管理 - **Primary Language**: PHP - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-08-27 - **Last Updated**: 2023-11-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # laravel-relations #### 介绍 laravel的模型关系管理 项目中一堆模型的关系 管理起来很不舒服 写个插件专门做关系管理 #### 软件架构 软件架构说明 #### 安装教程 ```shell # 安装 $ composer require stevema/laravel-relations ``` #### 使用说明 ```php # 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 说明 ```php 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; } } ``` ### 使用说明 - 从零开始使用 ```php # 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 中删除了 ``` ### 备注 1. 远程一对多关系 和 远程一对一关系 是一样的配置 一般远程一对一好像用不到吧 2. 如果使用 php artisan relation:use 拷贝到对应的模型中 请务必删除配置文件[/config/relations.php]中的关系模型[relations 里面的] 多次绑定可能除了问题找不到原因 3. 当 belongsTo,hasOne,hasOneThrough 和 morphOne 这些关联方法返回 null 的时候 你可以定义一个默认的模型返回。该模式通常被称为 空对象模式,它可以帮你省略代码中的一些条件判断。目前只支持 true false null array 还没支持闭包函数 有需要可以拷贝出来自定义