Laravel Eager Loading - 仅加载特定列

ipe*_*eer 32 php laravel laravel-4

我试图在laravel中加载一个模型,但只返回某些列.我不希望呈现整个急切的加载表.

public function car()
{
    return $this->hasOne('Car', 'id')->get(['emailid','name']);
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

log.ERROR:异常'Symfony\Component\Debug\Exception\FatalErrorException',带有消息'调用未定义的方法Illuminate\Database\Eloquent\Collection :: getAndResetWheres()'

rmo*_*bis 56

利用select()方法:

public function car() {
    return $this->hasOne('Car', 'id')->select(['owner_id', 'emailid', 'name']);
}
Run Code Online (Sandbox Code Playgroud)

注意:请记住添加分配给与两个表匹配的外键的列.例如,在我的例子中,我假设a Owner有一个Car,意味着分配给外键的列会是这样的owners.id = cars.owner_id,所以我必须添加owner_id到所选列的列表中;

  • 哦,你可能也需要使用外键.例如,如果它是'id`,你需要将`id`添加到`select()`'ed列. (9认同)
  • 不幸的是,这对我不起作用。如果我添加 select() 方法,则不会添加关系。如果我删除它,我会得到整行。 (4认同)
  • 我刚刚更新了原始答案,现在检查一下。基本上,如果在 `owners.id -> cars.owner_id` 上设置了 `Owner -> Car` 关系,您必须将 `owner_id` 添加到 `select()` ed 列列表中。 (2认同)
  • 花了几个小时在这上面,从来没有想过也必须选择 id。但现在它完全有道理。谢谢,我投了赞成票! (2认同)

Ali*_*Ali 16

此外,您不需要在模型和关系方法本身中指定获取特定列...您可以在需要时执行此操作...像这样:

$owners = Owner::
          with([
           'car' => function($q)
           {
            $q->select('id', 'owner_id', 'emailid', 'name');
           },
           'bike' => function($q)
           {
            $q->select('id', 'owner_id', 'emailid', 'name');
           }
          ])->
          get();
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您还可以获得相关模型的所有列.


Sha*_*war 9

您可以做的最简单的事情是查看文档并执行以下操作以仅获取特定列,而无需任何额外的代码行或闭包。按照步骤,

public function car(){
    return $this->hasOne('Car', 'id');
}
Run Code Online (Sandbox Code Playgroud)

然后当您急切加载关系时,只选择选定的列

$owner = $this->owner
->where('id', 23)
->with('car:id,owner_id,emailid,name')   //no space after comma(, ) and id has to be selected otherwise it will give null
Run Code Online (Sandbox Code Playgroud)

希望这有效,祝你有美好的一天。

  • 这就是我一直在寻找的!Laravel 文档没有给出此语法的任何提示,我只是在调试为什么我的 eagers 无法加载时才发现它。“id”注释是我唯一缺少的东西。你认为如果它丢失了,他们会注入它,或者至少记录它的存在。谢谢你!(更正:它已记录,但不在我所坚持的版本中 - 5.3。还要感谢@Bogdan 的附加说明。) (2认同)

Bog*_*dan 7

在你的控制器中你应该做的事情

App\Car::with('owner:id,name,email')->get();
Run Code Online (Sandbox Code Playgroud)

假设您有两个定义如下的模型

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Car extends Model
{
    protected $table = 'car';

    public function owner()
    {
        return $this->belongsTo('App\Owner', 'owner_id');
    }
}
Run Code Online (Sandbox Code Playgroud)

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Owner extends Model
{
    protected $table = 'owner';

    public function car()
    {
        return $this->hasMany('App\Car', 'owner_id');
    }
}
Run Code Online (Sandbox Code Playgroud)

你有两个表,如:

owners: id | name | email | phone | other_columns...
Run Code Online (Sandbox Code Playgroud)

cars: id | owner_id | make | color | other_columns...
Run Code Online (Sandbox Code Playgroud)

学分转到文档:eloquent-relations #eager-loading滚动到Eager Loading Specific Columns


cau*_*bug 5

shahrukh-anwarBogdan的答案都非常好,并引导我解决了这个问题的我的版本。

但是,我要添加一个关键部分来进行澄清(即使文档也没有提及)。

采取以下对我来说仍然很糟糕的内容:

Car::with('owner:id,name,email')->get(['year', 'vin']); 
Run Code Online (Sandbox Code Playgroud)

您很少在主模型 ( ->get(...)) 上看到特定的列选择,因此很容易忘记:您的选择需要外键列:

Car::with('owner:id,name,email')->get(['owner_id', 'year', 'vin']);
Run Code Online (Sandbox Code Playgroud)

当然,一旦您在使用闭包和此语法之间建立了心理联系,这似乎是显而易见的,但仍然很容易被忽视。

当您的表包含 30 多列并且只需要其中 3 列时,这可能会稍微降低您的内存负载。