Laravel Model 利用 Macroable 为数据模型添加宏能力
什么是ThinkSNS ?
ThinkSNS(简称TS),一款全平台综合性社交系统,为国内外大中小企业和创业者提供社会化软件研发及技术解决方案,目前最新版本为ThinkSNS+(简称TS+)、ThinkSNS V4、ThinkSNS【简】。
产生需求
在使用 Laravel 开发 ThinkSNS Plus 的时候,因为很多功能块都没有写在一个库里面,利用拓展包的形式添加实际功能,里面很多地方也用到了“多态多对多”的关系。问题来了,开发一个问答程序,想要给用户模型增加发布的问题或者回答的关系,起初是继承一份 User 模型,添加了关系,之后就发现问题了,因为用户的 tag 是使用多态多对多的关系,我通过继承的用户模型是无法拿到这种关系数据的因为 ***able_type 是 user 数据模型类名称或者别名。而我继承之后类也就发生改变了。
完成需求
随之想到,在 Laravel 中有一个 Trait 叫做 Macroable 然后发现 Builder 都有这种能力,而 Model 没有,随之也将这个 Trait 添加到要使用的model上,后来发现,如果其他模型也要用是不是也要再添加一次?随之写了一份 Trait :
trait Macroable
{
use \Illuminate\Support\Traits\Macroable {
__call as macroCall;
}
/**
* Get a relationship value from a method.
*
* @param string $key
* @return mixed
* @author Seven Du <shiweidu@outlook.com>
*/
public function getRelationValue($key)
{
$relation = parent::getRelationValue($key);
if (! $relation && static::hasMacro($key)) {
return $this->getRelationshipFromMethod($key);
}
return $relation;
}
/**
* Handle dynamic method calls into the model.
*
* @param string $method
* @param array $parameters
* @return mixed
* @author Seven Du <shiweidu@outlook.com>
*/
public function __call($method, $parameters)
{
if (static::hasMacro($method)) {
return $this->macroCall($method, $parameters);
}
return parent::__call($method, $parameters);
}
/**
* Handle dynamic static method calls into the method.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public static function __callStatic($method, $parameters)
{
return parent::__callStatic($method, $parameters);
}
}
只要在要使用的 model 中 use 即可。
使用
有了这个 Trait 那么我们添加到 User 模型中,就可以使用宏能力为其动态添加函数了:
User::macro('questions', function () {
return $this->hasMany(Question::class, 'user_id', 'id');
});
这样,我们可以直接 :
$questions = $user->questions;
拿到用户发布的所有问题了。
以上代码都来自于ThinkSNS Plus,看完整的开发代码可以看仓库:
GitHub: https://github.com/slimkit/thinksns-plus(开源不易,求 Star )
上一篇研发日记:如何在 Laravel 中 “规范” 的开发验证码发送功能
Laravel Model 利用 Macroable 为数据模型添加宏能力的更多相关文章
- ASP.NET MVC 5 - 给数据模型添加校验器
在本节中将会给Movie模型添加验证逻辑.并且确保这些验证规则在用户创建或编辑电影时被执行. 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(DRY ...
- [转]ASP.NET MVC 5 - 给数据模型添加校验器
在本节中将会给Movie模型添加验证逻辑.并且确保这些验证规则在用户创建或编辑电影时被执行. 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(DRY ...
- 利用VC助手(VA)添加注释
利用VC助手(VA)添加注释 今天想给自己写的代码加上版权信息,同时整理一下代码的注释.但是为了保持同样的格式,总是copy,显得有些繁琐.然后试图找解决方案.我用的是VS 2010, 刚开始是尝试了 ...
- Linux学习笔记——举例说,makefile 添加宏定义
0.前言 从学习C语言開始就慢慢開始接触makefile,查阅了非常多的makefile的资料但总感觉没有真正掌握makefile.假设自己动手写一个makefile总认为非常吃力. 所以特意 ...
- 利用OpenCV给图像添加中文标注
利用OpenCV给图像添加中文标注 : 参考:http://blog.sina.com.cn/s/blog_6bbd2dd101012dbh.html 和https://blog.csdn.net/ ...
- Android.bp 添加宏开关【转】
本文转载自:https://github.com/zzb2760715357/document/blob/master/android_doc/Android.bp%E6%B7%BB%E5%8A%A0 ...
- laravel项目利用twemproxy部署redis集群的完整步骤
Twemproxy是一个代理服务器,可以通过它减少Memcached或Redis服务器所打开的连接数.下面这篇文章主要给大家介绍了关于laravel项目利用twemproxy部署redis集群的相关资 ...
- 利用 Excel 写 C51 的宏定义
利用 Excel 写 C51 的宏定义 填好占空比,自动生成宏. #define LIGHT_LEVEL_00 0xFF #define LIGHT_LEVEL_10 0xE5 #define LIG ...
- 利用iTunes给MP3添加专辑插图
利用iTunes给MP3添加专辑插图 打开iTunes 准备好没有专辑插图的mp3文件和插图 将准备好的mp3文件拖入iTunes 右键菜单选择专辑信息选项 在专辑信息里面选择插图 点击左下角的添加插 ...
随机推荐
- Spark- Spark Yarn模式下跑yarn-client无法初始化SparkConext,Over usage of virtual memory
在spark yarn模式下跑yarn-client时出现无法初始化SparkContext错误. // :: INFO mapreduce.Job: Task Id : attempt_142829 ...
- 【详解】苹果AppStore审核被拒,原因终逃不过这些!
近日,相信很多开发者都留意到了: 苹果针对应用标题的审核确有明显的变严趋势!我们在<惊!苹果再次加强审核力度,众App纷纷止步应用标题>中也对该现象进行了详细的分析,并给出了相应的解决方案 ...
- 淘宝双十一页面(Flexible)demo
下面的代码是看了大漠 使用Flexible实现手淘H5页面的终端适配 做的一个demo. <!DOCTYPE html> <html lang="en" ng-a ...
- linux启动全过程
参考: http://www.staroceans.org/e-book/linux-bootstrap-1.html 1. MBR里的内容属于grub grub-2.02\grub-core\boo ...
- ASCII UNICODE UTF "口水文"
最近接了一个单是需要把非 UTF-8 (No BOM)编码的文件转换成 UTF-8 (No BOM),若此文件是 UTF-8 但带有 BOM ,需要转换成不带 BOM 的.于是开启了一天的阅读.首先花 ...
- java反射中Class对象详解和类名.class, class.forName(), getClass()区别
1.获得类型类 可以看到,对象a是A的一个实例,A是某一个类,在if语句中使用a.getClass()返回的结果正是类A的类型类,在Java中表示一个特定类型的类型类可以用“类型.class”的方式获 ...
- Money Systems
链接 分析:来看看背包九讲里面的一段话: 对于一个给定了背包容量.物品费用.物品间相互关系(分组.依赖等) 的背包问题,除了再给定每个物品的价值后求可得到的最大价值外,还可以得 到装满背包或将背包装至 ...
- forEach、for in 和for of的区别
forEach 不能使用break return 结束并退出循环 for in 和 for of 可以使用break return: for in遍历的是数组的索引(即键名),而for of遍历的是 ...
- TextBox的OnTextboxChanged事件里对Text重新赋值带中文, 导致崩溃
今天遇到一个超级bug, Textbox做了限制, 只能输入数字. 结果在搜狗输入法输入中文时导致崩溃, 出错信息如下: 未处理 System.InvalidOperationException ...
- python+ mysql存储二进制流的方式
很多时候我们为了管理方便会把依稀很小的图片存入数据库,有人可能会想这样会不会对数据库造成很大的压力,其实大家可以不用担心,因为我说过了,是存储一些很小的图片,几K的,没有问题的! 再者,在这里我们是想 ...