详解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 相关文章推荐
PHP5常用函数列表(分享)
Jun 07 PHP
php实现mysql数据库操作类分享
Feb 14 PHP
php读取目录所有文件信息dir示例
Mar 18 PHP
php实现按文件名搜索文件的远程文件查找器
May 10 PHP
ThinkPHP权限认证Auth实例详解
Jul 22 PHP
深入浅析php中sprintf与printf函数的用法及区别
Jan 08 PHP
php解决DOM乱码的方法示例代码
Nov 20 PHP
php一个文件搞定微信jssdk配置
Dec 12 PHP
php cookie用户登录的详解及实例代码
Jan 03 PHP
利用PHP判断是否是连乘数字串的方法示例
Jul 03 PHP
PHP实现的最大正向匹配算法示例
Dec 19 PHP
在Laravel中使用GuzzleHttp调用第三方服务的API接口代码
Oct 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
全国FM电台频率大全 - 16 河南省
2020/03/11 无线电
PHP中的加密功能
2006/10/09 PHP
一个简单的自动发送邮件系统(二)
2006/10/09 PHP
php FPDF类库应用实现代码
2009/03/20 PHP
php中使用临时表查询数据的一个例子
2013/02/03 PHP
php微信分享到朋友圈、QQ、朋友、微博
2019/02/18 PHP
JavaScript 组件之旅(三):用 Ant 构建组件
2009/10/28 Javascript
JavaScript XML和string相互转化实现代码
2011/07/04 Javascript
flash调用js中的方法,让js传递变量给flash的办法及思路
2013/08/07 Javascript
JS实现两个大数(整数)相乘
2014/04/28 Javascript
使用百度地图api实现根据地址查询经纬度
2014/12/11 Javascript
JavaScript获得当前网页来源页面(即上一页)的方法
2015/04/03 Javascript
JavaScript的9种继承实现方式归纳
2015/05/18 Javascript
JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
2015/10/08 Javascript
jquery获取复选框checkbox的值的简单实现方法
2016/05/26 Javascript
解析预加载显示图片艺术
2016/12/05 Javascript
JavaScript数组去重的6个方法
2017/01/21 Javascript
javascript Function函数理解与实战
2017/12/01 Javascript
Bootstrap模态对话框中显示动态内容的方法
2018/08/10 Javascript
vue 根据数组中某一项的值进行排序的方法
2018/08/30 Javascript
[28:28]Ti4 冒泡赛第二天NEWBEE vs NaVi 2
2014/07/15 DOTA
Python列表(list)、字典(dict)、字符串(string)基本操作小结
2014/11/28 Python
Python连接SQLServer2000的方法详解
2017/04/19 Python
django 常用orm操作详解
2017/09/13 Python
详解python里使用正则表达式的全匹配功能
2017/10/19 Python
python实现简易动态时钟
2018/11/19 Python
python中类的属性和方法介绍
2018/11/27 Python
python实现五子棋程序
2020/04/24 Python
CSS3——齿轮转动关键代码
2013/05/02 HTML / CSS
发现世界上最好的珠宝设计师:JewelStreet
2017/12/17 全球购物
时尚设计师手表:The Watch Cabin
2018/10/06 全球购物
日本化妆品植村秀俄罗斯官方网站:Shu Uemura俄罗斯
2020/02/01 全球购物
计算机应用专业学生的自我评价分享
2013/11/03 职场文书
警察思想汇报
2014/01/04 职场文书
师生聚会感言
2014/01/26 职场文书
详解Vue router路由
2021/11/20 Vue.js