Laravel Eager Loading - 仅加载特定列

时间:2013-06-07 23:14:15

标签: php laravel laravel-4

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

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

我收到以下错误:

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

8 个答案:

答案 0 :(得分:56)

使用select()方法:

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

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

答案 1 :(得分:12)

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

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

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

答案 2 :(得分:6)

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

的操作
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滚动到急切加载特定列

答案 3 :(得分:2)

有时候您需要使您的关系通用,以便可以轻松自在。

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;
}

答案 4 :(得分: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();

答案 5 :(得分:0)

您最容易做的就是阅读文档,并做以下事情来仅获取特定的列,而无需任何额外的代码行或闭包。遵循步骤

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

希望这能奏效,祝您生活愉快。

答案 6 :(得分:0)

shahrukh-anwarBogdan的答案都很好,使我得以解决此问题。

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

采取以下措施,但对我来说仍然如此:

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

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

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

当然,一旦您在使用Closure和此语法之间建立了精神上的联系,这似乎很明显,但仍然很容易忽略。

当表中有30列以上的列,而只需要3列时,这可能会使您的内存负载减少一点。

答案 7 :(得分:0)

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

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

如果您想为用户加载汽车,您可以在控制器上执行此操作

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

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

更多细节可以参考这个

Eager Loading Specific Columns