不,它不是,至少在没有一些额外工作的情况下不会,因为您的模型在实际加载之前不知道它支持哪些关系。
我在自己的一个 Laravel 包中遇到了这个问题。无法使用 Laravel 获取模型的关系列表。如果你看一下它们是如何定义的,那就很明显了。返回 Relation 对象的简单函数。你甚至无法通过php的反射类获取函数的返回类型,因此无法区分关系函数和任何其他函数。
您可以做的更简单的事情是定义一个添加所有关系的函数。
为此,您可以使用eloquents query scopes(感谢 Jarek Tkaczyk 在 cmets 中提到它)。
public function scopeWithAll($query)
{
$query->with('foo', 'bar', 'baz');
}
使用作用域而不是静态函数不仅可以让您直接在模型上使用您的函数,还可以在以任意顺序链接查询构建器方法(如where)时使用:
Model::where('something', 'Lorem ipsum dolor')->withAll()->where('somethingelse', '>', 10)->get();
获得支持关系的替代方法
虽然 Laravel 不支持开箱即用的类似功能,但您始终可以自己添加。
注释
我使用注解来确定一个函数是否在我上面提到的包中是一个关系。注释不是 php 的正式组成部分,但很多人使用 doc 块来模拟它们。
Laravel 5 也将在其路由定义中使用注释,所以我认为在这种情况下这不是坏习惯。优点是,您不需要维护单独的受支持关系列表。
为每个关系添加注释:
/**
* @Relation
*/
public function foo()
{
return $this->belongsTo('Foo');
}
并编写一个函数,解析模型中所有方法的doc块并返回名称。您可以在模型或父类中执行此操作:
public static function getSupportedRelations()
{
$relations = [];
$reflextionClass = new ReflectionClass(get_called_class());
foreach($reflextionClass->getMethods() as $method)
{
$doc = $method->getDocComment();
if($doc && strpos($doc, '@Relation') !== false)
{
$relations[] = $method->getName();
}
}
return $relations;
}
然后在你的 withAll 函数中使用它们:
public function scopeWithAll($query)
{
$query->with($this->getSupportedRelations());
}
有些喜欢 php 中的注释,有些则不喜欢。我喜欢这个简单的用例。
支持的关系数组
您还可以维护所有受支持关系的数组。但是,这需要您始终将其与可用关系同步,尤其是在涉及多个开发人员的情况下,这并不总是那么容易。
protected $supportedRelations = ['foo','bar', 'baz'];
然后在您的 withAll 函数中使用它们:
public function scopeWithAll($query)
{
return $query->with($this->supportedRelations);
}
你当然也可以override with like lukasgeiter mentioned in his answer。这似乎比使用withAll 更干净。但是,如果您使用注释或配置数组,则见仁见智。