Laravel eager loading with constraints

岁酱吖の 提交于 2019-12-20 06:25:06

问题


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?


回答1:


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.




回答2:


You don't neew those empty functions. You can directly put the relations on them.

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

Or alternatively you can put those on nested with method.

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


来源:https://stackoverflow.com/questions/29266117/laravel-eager-loading-with-constraints

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!