Laravel Eager Loading - Load only specific columns

前端 未结 7 1405
梦毁少年i
梦毁少年i 2020-12-05 00:35

I am trying to eager load a model in laravel but only return certain columns. I do not want the whole eager loaded table being presented.

public function car         


        
相关标签:
7条回答
  • 2020-12-05 00:40

    In your controller you should be doing something like

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

    Supposing that you have two models defined like below

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

    and

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

    and you have two tables something like:

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

    and

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

    Credits go to the docs: eloquent-relationships#eager-loading scroll to Eager Loading Specific Columns

    0 讨论(0)
  • 2020-12-05 00:46

    The answers from shahrukh-anwar and Bogdan are both excellent and led me to solving my version of this problem.

    However, there's one critical piece i would add for clarification (even the docs don't mention it).

    Take the following, which was still broken for me:

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

    You rarely see specific column selection on the primary model (->get(...)) so it's easy to forget: your selection needs the foreign key column:

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

    Sure, it seems obvious once you make the mental connection between with using a Closure and this syntax, but still, easy to overlook.

    When you have tables with 30+ columns and only need 3 of them, this might keep your memory load down a bit.

    0 讨论(0)
  • 2020-12-05 00:47

    Try WITH() & WHERE() conditions.

    $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();
    
    0 讨论(0)
  • 2020-12-05 00:48

    Sometimes you need to make your relation generic so that can call on your ease.

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

    and while fetching you can mention columns you need.

    $owners = Owner::with(['car' => function($query) { // eager loading
                $query->select('emailid','name');
               }
              ])->get();
    
    foreach($owners as $owner){
        $owner->car->emailid;
        $owner->car->name;
    }
    
    0 讨论(0)
  • 2020-12-05 00:59

    Also you don't need to specify getting specific columns in the model and the relationship method itself... You can do that whenever you need it... Like this:

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

    In this way you can also get all of the columns of the related model if you have ever needed to.

    0 讨论(0)
  • 2020-12-05 01:01

    Make use of the select() method:

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

    Note: Remember to add the columns assigned to the foreign key matching both tables. For instance, in my example, I assumed a Owner has a Car, meaning that the columns assigned to the foreign key would be something like owners.id = cars.owner_id, so I had to add owner_id to the list of selected columns;

    0 讨论(0)
提交回复
热议问题