详解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 什么是PEAR?
Mar 19 PHP
网站用php实现paypal整合方法
Nov 28 PHP
php中截取中文字符串的代码小结
Jul 17 PHP
php判断字符串在另一个字符串位置的方法
Feb 27 PHP
PHP使用ob_start生成html页面的方法
Nov 07 PHP
PHP 双链表(SplDoublyLinkedList)简介和使用实例
May 12 PHP
php验证邮箱和ip地址最简单方法汇总
Oct 30 PHP
Yii使用技巧大汇总
Dec 29 PHP
[原创]php集成安装包wampserver修改密码后phpmyadmin无法登陆的解决方法
Nov 23 PHP
thinkphp ajaxfileupload实现异步上传图片的示例
Aug 28 PHP
PHP基于堆栈实现的高级计算器功能示例
Sep 15 PHP
php使用fputcsv实现大数据的导出操作详解
Feb 27 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
自动跳转中英文页面
2006/10/09 PHP
php中cookie的作用域
2008/03/27 PHP
PHP保留两位小数并且四舍五入及不四舍五入的方法
2013/09/22 PHP
如何直接访问php实例对象中的private属性详解
2017/10/12 PHP
laravel异步监控定时调度器实例详解
2019/06/21 PHP
Vagrant(WSL)+PHPStorm+Xdebu 断点调试环境搭建
2019/12/13 PHP
javascript replace()正则替换实现代码
2010/02/26 Javascript
Jquery使用Firefox FireBug插件调试Ajax步骤讲解
2013/12/02 Javascript
JQuery对ASP.NET MVC数据进行更新删除
2016/07/13 Javascript
BootStrap树状图显示功能
2016/11/24 Javascript
微信小程序开发之入门实例教程篇
2017/03/07 Javascript
教你用十行node.js代码读取docx的文本
2017/03/08 Javascript
原生JS实现左右箭头选择日期实例代码
2017/03/14 Javascript
详解vue.js+UEditor集成 [前后端分离项目]
2017/07/07 Javascript
Vue v2.4中新增的$attrs及$listeners属性使用教程
2018/01/08 Javascript
Vue完整项目构建(进阶篇)
2018/02/10 Javascript
JS中实现隐藏部分姓名或者电话号码的代码
2018/07/17 Javascript
cdn模式下vue的基本用法详解
2018/10/07 Javascript
JS实现在线ps功能详解
2019/07/31 Javascript
Python处理XML格式数据的方法详解
2017/03/21 Python
Python实现删除文件中含“指定内容”的行示例
2017/06/09 Python
python+pyqt5实现24点小游戏
2019/01/24 Python
详解Python读取yaml文件多层菜单
2019/03/23 Python
关于tf.matmul() 和tf.multiply() 的区别说明
2020/06/18 Python
使用Python实现音频双通道分离
2020/12/25 Python
Python 实现RSA加解密文本文件
2020/12/30 Python
matplotlib bar()实现百分比堆积柱状图
2021/02/24 Python
阿玛尼美国官方网站:Armani.com
2016/11/25 全球购物
捷克原创男装和女装购物网站:Bolf.cz
2018/04/28 全球购物
印度尼西亚值得信赖的第一家网店:Bhinneka
2018/07/16 全球购物
保险专业大专生求职信
2013/10/26 职场文书
心得体会开头
2014/01/01 职场文书
餐饮业经理竞聘演讲稿
2014/01/14 职场文书
教师四风问题对照检查材料
2014/09/26 职场文书
党的群众路线教育实践活动学习计划
2014/11/03 职场文书
优秀班主任先进事迹材料
2014/12/16 职场文书