imanghafoori / eloquent-relativity
一种真正解耦eloquent模型的方法。
Requires
- php: ^7.1.3|7.2.*|7.3.*|7.4.*|8.0.*|8.1.*|8.2.*|8.3.*
- laravel/framework: ~5.1|6.*|7.*|8.*|9.*|10.*|11.*
Requires (Dev)
- mockery/mockery: *
- orchestra/testbench: ~3.0
Suggests
- imanghafoori/laravel-decorator: Allows you to easily apply the decorator pattern in a laravel app.
- imanghafoori/laravel-masterpass: You can easily set a master password without code change.
- imanghafoori/laravel-smart-facades: Automatic method injection when calling a method with Facades
- imanghafoori/laravel-widgetize: Gives you a better structure and caching opportunity for your web pages.
README
这允许您在运行时动态定义关系,从而真正解耦eloquent模型。
- 注意:在laravel 7.x或更高版本中不需要此包。
阅读更多: https://laravel.net.cn/docs/7.x/eloquent-relationships#dynamic-relationships
兼容性
Laravel版本5.5及以上,包括6版本
▶️ 一个阻止真正模块化的问题
让我们面对现实,想象你有一个模块化的博客应用程序。
那么,你想要添加一个评论
功能,以便用户可以在你的文章上发表评论。
在模块化结构中,你有2个模块(用户
模块和博客
模块),并且你将添加一个新的评论
模块。
▶️ 分析依赖和耦合
这里博客
模块“知道”并且“依赖于”用户
模块。
但是用户
模块不应该知道或关心博客
模块。博客是插件
,位于用户
模块之上。
现在我们想在用户
和博客
模块之上添加一个评论
模块。
▶️ 正确的方法
在一个真正模块化的系统中,当你添加评论
时,你不应该去修改用户
或博客
模块内的代码。(还记得SOLID中的开闭原则
吗?!?)
想象你在一个团队中,每个成员都在独立地工作。
博客
模块不是你的。你的队友负责它,并且被允许在上面编码。
但是当你开始定义评论
和用户
、文章
模型之间的eloquent关系时,你立即意识到你必须在其他模块的eloquent模型上添加代码来定义关系的逆。糟糕!
看看一切是如何指向内部的。
如果你查看用户
文件夹,你将找不到任何关于评论或文章的痕迹。
当添加新的评论
模块时,我们必须修改博客
和用户
模块的代码。
例如:你必须打开User.php
并定义
public function comments() { return $this->hasMany(Comment::class); }
这是不允许的,因为它从内部指向外部。
那么该怎么办呢?!
如何在不修改其他模块的情况下引入评论
?!( @_@)
▶️ 安装:(最痛苦的步骤)
composer require imanghafoori/eloquent-relativity (and take a coffee...)
现在安装完成,你必须首先使你的模型“相关”!!!
通过在你的eloquent模型上使用Imanghafoori\Relativity\DynamicRelations
特性。
因此,用户
、文章
、评论
必须具有这个特性。
现在来到了美好的部分
在CommentsServiceProvider.php
中
class CommentsServiceProvider { public function register () { User::has_many('comments', Comment::class); // instead of defining method on the User class. Article::has_many('comments', Comment::class); Comment::belongs_to('author', User::class); // inverse of relations Comment::belongs_to('article', Article::class); } }
现在你可以做这些查询
User::find(1)->comments; or User::find(1)->comments()->count();
所以,你不需要去用户
模型中定义一个方法...
public function comments() { return $this->hasMany(Comment::class); }
你在运行时从你的新模块中远程定义了方法
User::has_many('comments', Comment::class);
这里是一个支持的关联列表
- has_many
- has_one
- belongs_to
- belongs_to_many
- morph_to_many
- morph_many
- morph_one
- morph_to
- morphed_by_many
- has_many_through
它们接受与优雅等效的相应部分相同的参数。除了第一个参数应该是关系名称。
▶️ 额外功能
有时你需要调用关系上的额外方法。
User::has_many('comments', Comment::class)->orderBy('id', 'asc');
所有方法都对你可用。
- 强制预加载
在常规 eloquent 模型上,你可以定义
User extends Model { protected $with = ['comments']; }
相反,你可以
User::forceEagerLoading('comments');
记住,这应该在你的 Service Provider 的 boot
方法中,而不是在 register
方法中。
⭐ 您的星星让我们做得更多 ⭐
一如既往,如果您觉得这个包很有用,并且想鼓励我们维护和改进它,请按星按钮表达您的意愿。
▶️ 更多来自作者
Laravel 终结者
💎 一个最小化但强大的包,为您提供了重构控制器的机会。
Laravel 小部件化
💎 一个最小化但强大的包,为您的 Laravel 应用提供更好的结构和缓存机会。
Laravel 主密码
💎 一个简单的包,让您可以轻松地模拟用户。
Laravel 嘿,人
💎 它允许编写表达性和防御性的代码,这些代码与您的应用程序的其他部分解耦。
🍌 奖励我一个香蕉 🍌
这样我就会有能量为您启动下一个包。
Dodge Coin: DJEZr6GJ4Vx37LGF3zSng711AFZzmJTouN
LiteCoin: ltc1q82gnjkend684c5hvprg95fnja0ktjdfrhcu4c4
BitCoin: bc1q53dys3jkv0h4vhl88yqhqzyujvk35x8wad7uf9
Ripple: rJwrb2v1TR6rAHRWwcYvNZxjDN2bYpYXhZ
Etherium: 0xa4898246820bbC8f677A97C2B73e6DBB9510151e
Life is like riding a bicycle. To keep your balance you must keep moving.
"Albert Einstein"