// SomeModel
public function scopeWithAll($query)
{
$query->with([ ... all relations here ... ]);
// or store them in protected variable - whatever you prefer
// the latter would be the way if you want to have the method
// in your BaseModel. Then simply define it as [] there and use:
// $query->with($this->allRelations);
}
这样,您就可以随意使用它:
// static-like
SomeModel::withAll()->get();
// dynamically on the eloquent Builder
SomeModel::query()->withAll()->get();
SomeModel::where('something', 'some value')->withAll()->get();
9条答案
按热度按时间7kqas0il1#
不,它不是,至少没有一些额外的工作,因为您的模型不知道它支持哪些关系,直到他们实际上被加载。
我在我自己的一个Laravel包中遇到了这个问题。没有办法用Laravel得到一个模型的关系列表。如果你看看它们是如何定义的,这是很明显的。简单的函数返回一个
Relation
对象。你甚至不能用php的反射类得到一个函数的返回类型。因此没有办法区分关系函数和任何其他函数。为了简化这一过程,可以定义一个函数来添加所有关系,为此,可以使用雄辩的查询作用域(感谢Jarek Tkaczyk在评论中提到它)。
使用作用域而不是静态函数不仅允许您直接在模型上使用函数,而且还允许您以任何顺序链接查询构建器方法(例如
where
):获取受支持关系的替代方法
虽然Laravel不支持这样的开箱即用,你可以随时添加它自己。
注解
我使用了注解来确定一个函数是否是一个关系。注解不是php的正式部分,但是很多人使用doc块来模拟它们。Laravel 5也将在它的路由定义中使用注解,所以我认为在这种情况下这不是一个坏的做法。优点是,你不需要维护一个单独的支持关系的列表。
为每个关系添加注解:
然后编写一个函数,解析模型中所有方法的doc块并返回名称,你可以在模型或父类中这样做:
然后在
withAll
函数中使用它们:有些人喜欢php中的注解,有些人不喜欢。我喜欢这个简单的用例。
支持的关系数组
你也可以维护所有支持的关系的数组。但是这需要你总是将它与可用的关系同步,特别是当有多个开发人员参与时,并不总是那么容易。
然后在
withAll
函数中使用它们:当然,你也可以使用override
with
like lukasgeiter mentioned in his answer,这看起来比使用withAll
更简洁,但如果你使用注解或配置数组,那就见仁见智了。vmjh9lq92#
没有办法知道所有的关系是什么,如果不指定他们自己。如何其他答案张贴是好的,但我想补充几件事。
基本型号
我有一种感觉,你想在多个模型中这样做,所以如果你还没有的话,首先我会创建一个
BaseModel
。“配置”数组
我建议您使用成员变量,而不是将关系硬编码到方法中。正如您在上面看到的,我已经添加了
$allRelations
。请注意,您不能将其命名为$relations
,因为Laravel已经在内部使用了它。覆盖
with()
既然你想要
with(*)
,你也可以这样做。把这个添加到BaseModel
(By这个函数的某些部分来自原始的Model类)
用法
js5cn81o3#
我不会像建议的那样使用
static
方法,因为......它是Eloquent ;)只需利用它已经提供得功能-范围.当然它不会为你做它(主要问题),但这绝对是要走的路:
这样,您就可以随意使用它:
而且,事实上,你可以让Eloquent为你做这件事,就像
Doctrine
做的那样--使用doctrine/annotations
和DocBlocks。你可以这样做:在这里包含它有点太长了,所以了解它是如何工作的:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html
nwlqm0z14#
由于我遇到过类似的问题,并找到了一个很好的解决方案,这里没有描述,也不需要填充一些自定义数组或其他什么,我会在未来发布它。
我首先创建一个名为
RelationsManager
的trait
:现在你可以在任何类上使用它,比如-
然后当您需要从数据库中获取它们时:
一些注意事项--我的关系类示例列表不包括变形关系,所以如果你也想得到它们--你需要把它们添加到
$relationClasses
变量中。mgdq6dx15#
您可以尝试使用反映来侦测特定于模型的方法,例如:
然后尝试在一个控制良好的
try/catch
中加载每一个。Laravel的Model类有一个load和一个loadMissing方法用于快速加载。请参阅api reference.
e37o9pze6#
您可以在模型中创建方法
并调用
Model::withAllRelations()
或者
$instance->withAllRelations()->first(); // or ->get()
个af7jpaap7#
对于某个模型,你不能有一个动态的关系加载。你需要告诉模型支持哪些关系。
hs1ihplo8#
composer 需要adideas/laravel-get-relationship-雄辩的-模型
https://packagist.org/packages/adideas/laravel-get-relationship-eloquent-model
拉瑞威把关系弄得全是口若悬河的模特!
您不需要知道模型中方法的名称就可以做到这一点。有了一个或多个Eloquent模型,多亏了这个包,您可以在运行时获得它的所有关系及其类型
kyxcudwk9#
最佳解决方案
首先创建一个名为RelationsManager特征:
现在你可以在任何类上使用它,比如-
然后当您需要从数据库中获取它们时:
此解决方案仅适用于PHP7或更高版本。
已完成