详解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 文件上传系统手记
Oct 26 PHP
PHP三元运算符的结合性介绍
Jan 10 PHP
windows下zendframework项目环境搭建(通过命令行配置)
Dec 06 PHP
phpize的深入理解
Jun 03 PHP
Youku 视频绝对地址获取的方法详解
Jun 26 PHP
一个PHP的远程图片抓取函数分享
Sep 25 PHP
浅谈php优化需要注意的地方
Nov 27 PHP
php程序内部post数据的方法
Mar 31 PHP
Joomla实现组件中弹出一个模式(modal)窗口的方法
May 04 PHP
详解php实现页面静态化原理
Jun 21 PHP
Laravel多域名下字段验证的方法
Apr 04 PHP
Laravel 6.2 中添加了可调用容器对象的方法
Oct 22 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
在php中取得image按钮传递的name值
2006/10/09 PHP
PHP 柱状图实现代码
2009/12/04 PHP
PHP删除数组中空值的方法介绍
2014/04/14 PHP
PHP实现抓取HTTPS内容
2014/12/01 PHP
php使用CURL不依赖COOKIEJAR获取COOKIE的方法
2015/06/17 PHP
PHP策略模式定义与用法示例
2017/07/27 PHP
JavaScript Event学习第八章 事件的顺序
2010/02/07 Javascript
两个Javascript小tip资料
2010/11/23 Javascript
jquery实现盒子下拉效果示例代码
2013/09/12 Javascript
基于dropdown.js实现的两款美观大气的二级导航菜单
2015/09/02 Javascript
JS函数多个参数默认值指定方法分析
2016/11/28 Javascript
总结js函数相关知识点
2018/02/27 Javascript
Vue中对比scoped css和css module的区别
2018/05/17 Javascript
使用express获取微信小程序二维码小记
2019/05/21 Javascript
layui关闭弹窗后刷新主页面和当前更改项的例子
2019/09/06 Javascript
Vue v-text指令简单使用方法示例
2019/09/19 Javascript
微信小程序canvas截取任意形状的实现代码
2020/01/13 Javascript
Javascript实现秒表计时游戏
2020/05/27 Javascript
微信小程序picker组件两列关联使用方式
2020/10/27 Javascript
python正则表达式去掉数字中的逗号(python正则匹配逗号)
2013/12/25 Python
Python最基本的输入输出详解
2015/04/25 Python
Tornado高并发处理方法实例代码
2018/01/15 Python
python一键去抖音视频水印工具
2018/09/14 Python
在Pycharm中设置默认自动换行的方法
2019/01/16 Python
对python中基于tcp协议的通信(数据传输)实例讲解
2019/07/22 Python
pycharm内无法import已安装的模块问题解决
2020/02/12 Python
在pycharm中创建django项目的示例代码
2020/05/28 Python
pyCharm 设置调试输出窗口中文显示方式(字符码转换)
2020/06/09 Python
Jmeter调用Python脚本实现参数互相传递的实现
2021/01/22 Python
国际知名设计师时装商店:Coggles
2016/09/05 全球购物
Java TransactionAPI (JTA) 主要包含几部分
2012/12/07 面试题
优秀演讲稿范文
2013/12/29 职场文书
关于清明节的演讲稿2015
2015/03/18 职场文书
毕业论文答辩开场白和答辩技巧
2015/05/27 职场文书
人为什么会“幸灾乐祸”?
2019/08/06 职场文书
掌握这项技巧,一年阅读300本书不是梦
2019/09/12 职场文书