加载模型的所有关系 [英] Load all relationships for a model

查看:86
本文介绍了加载模型的所有关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,我渴望加载一段关系:

Usually to eager load a relationship I would do something like this:

Model::with('foo', 'bar', 'baz')...

一个解决方案可能是设置$with = ['foo','bar','baz'],但是每当我调用Model

A solution might be to set $with = ['foo','bar','baz'] however that will always load these three relations whenever I call Model

是否可以执行以下操作:Model::with('*')?

Is it possible to do something like this: Model::with('*')?

推荐答案

不是,至少没有做一些额外的工作,因为您的模型在实际加载之前不知道它支持哪种关系.

No it's not, at least not without some additional work, because your model doesn't know which relations it supports until they are actually loaded.

我在自己的Laravel软件包之一中遇到了这个问题.无法获得与Laravel的模型关系的列表.但是,如果您看一下它们的定义,这是很明显的.返回Relation对象的简单函数.您甚至无法使用php的反射类获得函数的返回类型,因此无法区分关系函数和任何其他函数.

I had this problem in one of my own Laravel packages. There is no way to get a list of the relations of a model with Laravel. It's pretty obvious though if you look at how they are defined. Simple functions which return a Relation object. You can't even get the return type of a function with php's reflection classes, so there is no way to distinguish between a relation function and any other function.

您可以做的就是定义一个添加所有关系的函数,以使其变得更容易. 为此,您可以使用雄辩者查询范围(感谢Jarek Tkaczyk提到在评论中).

What you can do to make it easier is defining a function that adds all the relationships. To do this you can use eloquents query scopes (Thanks to Jarek Tkaczyk for mentioning it in the comments).

public function scopeWithAll($query) 
{
    $query->with('foo', 'bar', 'baz');
}

使用范围而不是静态函数,不仅使您不仅可以直接在模型上使用函数,而且还可以在以任意顺序链接诸如where之类的查询构建器方法时使用

Using scopes instead of static functions allows you to not only use your function directly on the model but for example also when chaining query builder methods like where in any order:

Model::where('something', 'Lorem ipsum dolor')->withAll()->where('somethingelse', '>', 10)->get();

获得支持关系的替代方法

尽管Laravel不支持此类功能,但您仍可以自己添加.

Alternatives to get supported relations

Although Laravel does not support something like that out of the box you can allways add it yourself.

我在上面提到的程序包中使用批注来确定函数是否是关系.注释不是php的正式组成部分,但是很多人使用doc块来模拟它们. Laravel 5还将在其路由定义中使用注释,因此我认为在这种情况下这不是一个坏习惯.好处是,您不需要维护受支持关系的单独列表.

I used annotations to determine if a function is a relation or not in my package mentioned above. Annotations are not officially part of php but a lot of people use doc blocks to simulate them. Laravel 5 is going to use annotations in its route definitions too so I figuered it not to be bad practice in this case. The advantage is, that you don't need to maintain a seperate list of supported relations.

为每个关系添加注释:

/**
 * @Relation
 */
public function foo() 
{
    return $this->belongsTo('Foo');
}

并编写一个函数,该函数分析模型中所有方法的doc块并返回名称.您可以在模型或父类中执行此操作:

And write a function that parses the doc blocks of all methods in the model and returns the name. You can do this in a model or in a parent class:

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函数中使用它们:

And then just use them in your withAll function:

public function scopeWithAll($query) 
{
    $query->with($this->getSupportedRelations());
}

有些像php中的注释,有些则没有.我喜欢这个简单的用例.

Some like annotations in php and some don't. I like it for this simple use case.

您还可以维护所有支持的关系的数组.但是,这需要您始终将其与可用的关系保持同步,尤其是在涉及多个开发人员的情况下,这并非总是那么容易.

You can also maintain an array of all the supported relations. This however needs you to always sync it with the available relations which, especially if there are multiple developers involved, is not allways that easy.

protected $supportedRelations = ['foo','bar', 'baz'];

然后在withAll函数中使用它们:

And then just use them in your withAll function:

public function scopeWithAll($query) 
{
    return $query->with($this->supportedRelations);
}

您当然也可以覆盖with,就像他的回答中提到的lukasgeiter 一样.这似乎比使用withAll更干净.但是,如果您使用批注或配置数组,则是个问题.

You can of course also override with like lukasgeiter mentioned in his answer. This seems cleaner than using withAll. If you use annotations or a config array however is a matter of opinion.

这篇关于加载模型的所有关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆