详解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二分法在IP地址查询中的应用
Aug 12 PHP
PHP 组件化编程技巧
Jun 06 PHP
简单的php写入数据库类代码分享
Jul 26 PHP
PHP中全面阻止SQL注入式攻击分析小结
Jan 30 PHP
PHP函数microtime()用法与说明
Dec 04 PHP
两种设置php载入页面时编码的方法
Jul 29 PHP
php动态函数调用方法
May 21 PHP
PHP使用CURL模拟登录的方法
Jul 08 PHP
简单谈谈php浮点数精确运算
Mar 10 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
Aug 17 PHP
PHP设计模式之适配器模式定义与用法详解
Apr 03 PHP
PHP连接MySQL数据库并以json格式输出
May 21 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
哪吒敖丙传:新人物二哥敖乙出场 小敖丙奶气十足
2020/03/08 国漫
PHP中::、-&amp;gt;、self、$this几种操作符的区别介绍
2013/04/24 PHP
JoshChen_web格式编码UTF8-无BOM的小细节分析
2013/08/16 PHP
php使用array_rand()函数从数组中随机选择一个或多个元素
2014/04/28 PHP
PHP结合jQuery.autocomplete插件实现输入自动完成提示的功能
2015/04/27 PHP
php微信开发之图片回复功能
2018/06/14 PHP
Laravel框架Auth用户认证操作实例分析
2019/09/29 PHP
经典的带阴影的可拖动的浮动层
2006/06/26 Javascript
jQuery 版元素拖拽原型代码
2011/04/25 Javascript
细说javascript函数从函数的构成开始
2013/08/29 Javascript
详解JavaScript编程中正则表达式的使用
2015/10/25 Javascript
JavaScript必知必会(三) String .的方法来自何方
2016/06/08 Javascript
Ionic 2 实现列表滑动删除按钮的方法
2017/01/22 Javascript
AngulerJS学习之按需动态加载文件
2017/02/13 Javascript
js时间戳和c#时间戳互转方法(推荐)
2017/02/15 Javascript
使用canvas及js简单生成验证码方法
2017/04/02 Javascript
详解用node编写自己的cli工具
2017/05/23 Javascript
angularjs定时任务的设置与清除示例
2017/06/02 Javascript
详解用node.js实现简单的反向代理
2017/06/26 Javascript
js中变量的连续赋值(实例讲解)
2017/07/08 Javascript
总结js函数相关知识点
2018/02/27 Javascript
Vuex中的State使用介绍
2019/01/19 Javascript
JavaScript变速动画函数封装添加任意多个属性
2019/04/03 Javascript
详解Vue之事件处理
2020/07/10 Javascript
[44:30]完美世界DOTA2联赛PWL S2 GXR vs Magma 第一场 11.25
2020/11/26 DOTA
使用python Fabric动态修改远程机器hosts的方法
2018/10/26 Python
python读取有密码的zip压缩文件实例
2019/02/08 Python
将tensorflow模型打包成PB文件及PB文件读取方式
2020/01/23 Python
CSS3 完美实现圆角效果
2009/07/13 HTML / CSS
AP澳洲中文网:澳洲正品直邮,包税收件无忧
2019/07/12 全球购物
Tomcat中怎么使用log4j输出所有的log
2016/07/07 面试题
J2EE的优越性主要表现在哪些方面
2016/03/28 面试题
教师绩效考核方案
2014/01/21 职场文书
大学生个人自荐信
2014/02/24 职场文书
活动总结的格式
2014/05/07 职场文书
「天才王子的赤字国家重生术」妮妮姆·拉雷粘土人开订
2022/03/21 日漫