详解Laravel设置多态关系模型别名的方式


Posted in PHP onOctober 17, 2019

作为 Laravel 的重度使用者肯定都对多态关系不默生,以官方文档为例,文章有标签,视频有标签,那么文章和视频这些模型与标签模型的关系就是 多态多对多(Many To Many (Polymorphic))

如果我们给 ID 为 1 的文章打上两个标签,数据库标签关系表的的存储结果就是这样子:

> select * from taggables;
+--------+-------------+---------------+
| tag_id | taggable_id | taggable_type |
+--------+-------------+---------------+
|  1 |   1 | App\Post  |
|  2 |   1 | App\Post  |
+--------+-------------+---------------+

相信有不少人和我一样希望 taggable_type 的值不要直接用模型类名,而是使用表名: posts 。官方文档的建议是:

use Illuminate\Database\Eloquent\Relations\Relation;

Relation::morphMap([
 'posts' => 'App\Post',
 'videos' => 'App\Video',
]);

https://laravel.com/docs/6.x/eloquent-relationships#custom-polymorphic-types

我们可以将这个定义写到 AppServiceProvider 中,但是有一个非常严重的问题: 我们在新增或者删除模型的时候,会很容易忘记去更新这个定义 。我已经至少出现这个问题 3 次了,所以我一直在纠结有没有更好的方法,今天突然灵机一动,实现了一个看起来似乎是一个不错的方式,分享给大家。

思路来源

我尝试跟踪了一遍源码,发现模型中有一个方法 getMorphClass ,多态关联的时候,就是用它来取目标对象的类型名称的,默认返回类名:

public function getMorphClass()
{
 $morphMap = Relation::morphMap();
 if (! empty($morphMap) && in_array(static::class, $morphMap)) {
  return array_search(static::class, $morphMap, true);
 }
 return static::class;
}

那么,只要我们在模型中覆盖这个方法便可以方便的实现目标了。

实现目标

我们有两个选择去实现它:

  1. 创建一个模型基类覆盖这个方法,所有的模型都来集成它即可;
  2. 创建一个 trait,在需要的模型中引入它。

我当然会选择 trait 方式来实现,不管从定义还是代码耦合度上,使用 trait 来解决这类特性需求都是再适合不过了,如果你对 trait 还不太熟悉,可以阅读我之前的文章: 《我所理解的 PHP Trait》

我们的目标是使用表名来做为关系类别名,那么在模型中如何获取表名呢,直接使用模型的 getTable 即可,那么整个 trait 的实现如下:

app/Traits/UseTableNameAsMorphClass.php
<?php
namespace App\Traits;
trait UseTableNameAsMorphClass
{
 public function getMorphClass()
 {
  return $this->getTable();
 }
}

然后在我们需要用到关系类型的模型中引入它即可:

<?php
namespace App;
use App\Traits\UseTableNameAsMorphClass;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
 use UseTableNameAsMorphClass;

 //...
}

友情提示

当然,如果你习惯给表名加前缀,或者你的表名与模型名不太一致,那么,你只需要修改 trait 中 getMorphClass 的实现即可,我个人的习惯是模型名就是表名的单数,不带前缀。

总结

以上所述是小编给大家介绍的Laravel设置多态关系模型别名的方式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

PHP 相关文章推荐
php md5下16位和32位的实现代码
Apr 09 PHP
php 删除无限级目录与文件代码共享
Nov 22 PHP
从Web查询数据库之PHP与MySQL篇
Sep 25 PHP
PHP运行环境配置与开发环境的配置(图文教程)
Jun 04 PHP
解析php中var_dump,var_export,print_r三个函数的区别
Jun 21 PHP
解析PHP跳出循环的方法以及continue、break、exit的区别介绍
Jul 01 PHP
PHP实现获取域名的方法小结
Nov 05 PHP
php数组查找函数总结
Nov 18 PHP
PHP封装的数据库保存session功能类
Jul 11 PHP
PHP高精确度运算BC函数库实例详解
Aug 15 PHP
PHP实现正则表达式分组捕获操作示例
Feb 03 PHP
TP5多入口设置实例讲解
Dec 15 PHP
Laravel 5.5 异常处理 &amp; 错误日志的解决
Oct 17 #PHP
PHP封装请求类实例分析【基于Yii框架】
Oct 17 #PHP
使用laravel指定日志文件记录任意日志
Oct 17 #PHP
Laravel 修改默认日志文件名称和位置的例子
Oct 17 #PHP
thinkPHP事务操作简单案例分析
Oct 17 #PHP
使用laravel根据用户类型来显示或隐藏字段
Oct 17 #PHP
laravel model模型定义实现开启自动管理时间created_at,updated_at
Oct 17 #PHP
You might like
利用discuz自带通行证整合dedecms的方法以及文件下载
2007/03/06 PHP
php实现过滤字符串中的中文和数字实例
2015/07/29 PHP
php+jquery+html实现点击不刷新加载更多的实例代码
2016/08/12 PHP
PHP中include()与require()的区别说明
2017/02/14 PHP
php中curl和soap方式请求服务超时问题的解决
2018/06/11 PHP
一些有关检查数据的JS代码
2006/09/07 Javascript
JavaScript 异步方法队列链实现代码分析
2010/06/05 Javascript
jquery ready(fn)事件使用介绍
2013/08/21 Javascript
JavaScript判断图片是否已经加载完毕的方法汇总
2016/02/05 Javascript
jQuery实现带延时功能的水平多级菜单效果【附demo源码下载】
2016/09/21 Javascript
Javascript 普通函数和构造函数的区别
2016/11/05 Javascript
基于JQuery实现的跑马灯效果(文字无缝向上翻动)
2016/12/02 Javascript
微信小程序 引用其他js文件实现代码
2017/02/22 Javascript
JavaScript数据结构之二叉树的查找算法示例
2017/04/13 Javascript
JS中this的指向以及call、apply的作用
2018/05/06 Javascript
VeeValidate在vue项目里表单校验应用案例
2018/05/09 Javascript
JS复杂判断的更优雅写法代码详解
2018/11/07 Javascript
JS继承定义与使用方法简单示例
2020/02/19 Javascript
Vue2.x和Vue3.x的双向绑定原理详解
2020/11/05 Javascript
对numpy中shape的深入理解
2018/06/15 Python
利用python实现对web服务器的目录探测的方法
2019/02/26 Python
Python将字符串常量转化为变量方法总结
2019/03/17 Python
pip指定python位置安装软件包的方法
2019/07/12 Python
python-sys.stdout作为默认函数参数的实现
2020/02/21 Python
pyautogui自动化控制鼠标和键盘操作的步骤
2020/04/01 Python
python中urllib.request和requests的使用及区别详解
2020/05/05 Python
利用python清除移动硬盘中的临时文件
2020/10/28 Python
CSS3不透明度实例讲解
2016/04/26 HTML / CSS
StubHub墨西哥:购买和出售您的门票
2016/09/17 全球购物
英国领先的独立酒精饮料零售商:DrinkSupermarket
2021/01/13 全球购物
外贸业务员求职自荐信分享
2013/09/21 职场文书
员工工作表扬信范文
2014/01/13 职场文书
《再别康桥》教学反思
2014/02/12 职场文书
小学班主任寄语大全
2014/04/04 职场文书
供电工程专业求职信
2014/08/09 职场文书
Kubernetes关键组件与结构组成介绍
2022/03/31 Servers