Laravel急于加载约束 [英] Laravel eager loading with constraints

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

问题描述

所以我的模型有2个简单的关系.然后,渴望的加载就可以像这样完美工作:

Entry::with('author', 'lastModifiedBy')->...;

但是说我想添加一个受约束的新关系.例如:

public function foo() {
    return $this->hasOne('Foo')->latest('id');
}

然后急于加载这种关系,Laravel建议这样做:

Entry::with(array('foo' => function($query) use ($id) {
    $query->where('user_id', $id);
}))->...;

但是如果我想包含我的authorlastModifiedBy关系,我最终不得不做:

Entry::with(array(
    'foo' => function($query) use ($id) {
        $query->where('user_id', $id);
    },
   'author' => function() { },
   'lastModifiedBy' => function() { }
))->...;

我必须给这两个关系一个空函数.在没有这些空函数的丑陋的情况下,有没有一种更简单的方法?

解决方案

不需要空函数. Laravel非常聪明,能够处理带有约束的混合关系,而没有约束的情况.

Entry::with(array(
    'foo' => function($query) use ($id) {
        $query->where('user_id', $id);
    },
    'author',
    'lastModifiedBy'
))->...;

工作原理

Laravel区分这两种方式:

Illuminate\Database\Eloquent\Builder@parseRelations

foreach ($relations as $name => $constraints)
{
    // If the "relation" value is actually a numeric key, we can assume that no
    // constraints have been specified for the eager load and we'll just put
    // an empty Closure with the loader so that we can treat all the same.
    if (is_numeric($name))
    {
        $f = function() {};
        list($name, $constraints) = array($constraints, $f);
    }

如评论所述,如果数组项的键为数字,Laravel实际上会自己添加空闭包.

So my model has 2 simple relationships. Then eager loading works perfectly like this:

Entry::with('author', 'lastModifiedBy')->...;

But say I want to add a new relationship that takes a constraint. For example:

public function foo() {
    return $this->hasOne('Foo')->latest('id');
}

Then to eager load this relationship, Laravel suggests doing it like so:

Entry::with(array('foo' => function($query) use ($id) {
    $query->where('user_id', $id);
}))->...;

But if I want to include my author and lastModifiedBy relationships, I end up having to do:

Entry::with(array(
    'foo' => function($query) use ($id) {
        $query->where('user_id', $id);
    },
   'author' => function() { },
   'lastModifiedBy' => function() { }
))->...;

I have to give those 2 relationships an empty function. Is there a simpler way to do this without the ugliness of these empty functions?

解决方案

The empty functions are not necessary. Laravel is smart enough to be able to work with a mixed array of relations with constraints and such without them.

Entry::with(array(
    'foo' => function($query) use ($id) {
        $query->where('user_id', $id);
    },
    'author',
    'lastModifiedBy'
))->...;

How it works

Here's how Laravel distinguishes between the two:

in Illuminate\Database\Eloquent\Builder@parseRelations

foreach ($relations as $name => $constraints)
{
    // If the "relation" value is actually a numeric key, we can assume that no
    // constraints have been specified for the eager load and we'll just put
    // an empty Closure with the loader so that we can treat all the same.
    if (is_numeric($name))
    {
        $f = function() {};
        list($name, $constraints) = array($constraints, $f);
    }

As the comment describes, Laravel actually adds the empty closure by itself if the key of the array item is numeric.

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

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