41

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

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

我收到以下错误:

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

4

9 回答 9

68

使用select()方法:

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

注意:请记住添加分配给匹配两个表的外键的列。例如,在我的示例中,我假设 aOwner具有Car,这意味着分配给外键的列将类似于owners.id = cars.owner_id,因此我必须添加owner_id到选定列的列表中;

于 2013-06-07T23:57:33.203 回答
23

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

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

通过这种方式,如果您需要,您还可以获得相关模型的所有列。

于 2015-12-01T11:29:00.670 回答
18

在您的控制器中,您应该执行类似的操作

App\Car::with('owner:id,name,email')->get();

假设您定义了两个模型,如下所示

<?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');
    }
}

<?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');
    }
}

你有两张桌子,比如:

owners: id | name | email | phone | other_columns...

cars: id | owner_id | make | color | other_columns...

归功于文档:eloquent-relationships#eager-loading scroll to Eager Loading Specific Columns

于 2017-12-20T08:36:35.780 回答
9

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

public function car(){
    return $this->hasOne('Car', 'id');
}

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

$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

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

于 2019-07-26T10:37:08.413 回答
3

shahrukh-anwarBogdan的答案都很出色,让我解决了这个问题。

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

采取以下,这对我来说仍然是坏的:

Car::with('owner:id,name,email')->get(['year', 'vin']); 

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

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

当然,一旦你在使用闭包和这种语法之间建立了心理联系,这似乎很明显,但仍然很容易被忽视。

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

于 2020-09-24T20:24:37.613 回答
0

尝试WITH() & WHERE()条件。

$user_id = 1; // for example

Post::with(array('user'=>function($query) use ($user_id ){
            $query->where('user_id','=',$user_id );
            $query->select('user_id','username');
        }))->get();
于 2019-06-25T05:26:20.617 回答
0

有时您需要使您的关系通用化,以便您轻松自如。

public function car()
{
    return $this->hasOne('Car', 'id');
}

并且在获取时您可以提及您需要的列。

$owners = Owner::with(['car' => function($query) { // eager loading
            $query->select('emailid','name');
           }
          ])->get();

foreach($owners as $owner){
    $owner->car->emailid;
    $owner->car->name;
}
于 2020-10-21T13:07:32.373 回答
0

也可以在预先加载时指定要加载的特定列。假设你有这个模态类

class user extends Model {
  public function car()
    {
      return $this->hasOne('Car', 'id')->get(['emailid','name']);
    }
}

如果你想用它的车加载用户,你可以在你的控制器上执行此操作

User::with(['car:id,emailid,name'])->get(); 

:-注意不要忘记在你想得到的列中添加外键,否则它现在可以工作了。你需要一个汽车模型以及反向关系。

有关更多详细信息,您可以参考此

急切加载特定列

于 2021-04-01T08:40:48.260 回答
0

确保在使用急切加载时放置 id 列

Voucher::with(['storeInfo:id,name as branchName,code as branchCode'])->get();

模型中

public function storeInfo() { return $this->belongsTo(Branch::class,'branch_id'); }

于 2021-10-02T01:51:33.570 回答