通常渴望加载一段关系,我会做这样的事情:
Model::with('foo', 'bar', 'baz')...
解决方案可能是设置一个,$with = ['foo','bar','baz']
但是每次我打电话时,总是加载这三个关系Model
是否有可能做这样的事情:Model::with('*')
?
不,不是,至少没有一些额外的工作,因为在实际加载模型之前,您的模型不知道它支持哪种关系。
我在自己的Laravel软件包之一中遇到了这个问题。无法获得与Laravel的模型关系的列表。但是,如果您看一下它们的定义,这是很明显的。返回Relation
对象的简单函数。您甚至无法使用php的反射类获得函数的返回类型,因此无法区分关系函数和任何其他函数。
您可以做的就是简化定义添加所有关系的函数。为此,您可以使用雄辩的查询范围(感谢Jarek Tkaczyk在评论中提到它)。
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);
}
当然,您也可以with
像在他的回答中提到的lukasgeiter那样重写。这似乎比使用干净withAll
。但是,如果您使用注释或配置数组,则是一个意见问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句