Laravel Eloquent: How to get only certain columns from joined tables

PhpLaravelEloquent

Php Problem Overview


I have got 2 joined tables in Eloquent namely themes and users.

theme model:

public function user() {
  return $this->belongs_to('User');
}

user model:

public function themes() {
  return $this->has_many('Theme');
}

My Eloquent api call looks as below:

return Response::eloquent(Theme::with('user')->get());

Which returns all columns from theme (that's fine), and all columns from user (not fine). I only need the 'username' column from the user model, how can I limit the query to that?

Php Solutions


Solution 1 - Php

Change your model to specify what columns you want selected:

public function user() {
  return $this->belongs_to('User')->select(array('id', 'username'));
}

And don't forget to include the column you're joining on.

Solution 2 - Php

For Laravel >= 5.2

Use the ->pluck() method

$roles = DB::table('roles')->pluck('title');

> If you would like to retrieve an array containing the values of a single column, you may use the pluck method


For Laravel <= 5.1

Use the ->lists() method

$roles = DB::table('roles')->lists('title');

> This method will return an array of role titles. You may also specify a custom key column for the returned array:

Solution 3 - Php

You can supply an array of fields in the get parameter like so:

return Response::eloquent(Theme::with('user')->get(array('user.username'));

UPDATE (for Laravel 5.2) From the docs, you can do this:

$response = DB::table('themes')
    ->select('themes.*', 'users.username')
    ->join('users', 'users.id', '=', 'themes.user_id')
    ->get();

Solution 4 - Php

I know, you ask for Eloquent but you can do it with Fluent Query Builder

$data = DB::table('themes')
    ->join('users', 'users.id', '=', 'themes.user_id')
    ->get(array('themes.*', 'users.username'));

Solution 5 - Php

This is how i do it

$posts = Post::with(['category' => function($query){
        $query->select('id', 'name');
      }])->get();

First answer by user2317976 did not work for me, i am using laravel 5.1

Solution 6 - Php

Using with pagination

$data = DB::table('themes')
->join('users', 'users.id', '=', 'themes.user_id')
->select('themes.*', 'users.username')
->paginate(6);

Solution 7 - Php

Another option is to make use of the $hidden property on the model to hide the columns you don't want to display. You can define this property on the fly or set defaults on your model.

public static $hidden = array('password');

Now the users password will be hidden when you return the JSON response.

You can also set it on the fly in a similar manner.

User::$hidden = array('password');

Solution 8 - Php

user2317976 has introduced a great static way of selecting related tables' columns.

Here is a dynamic trick I've found so you can get whatever you want when using the model:

return Response::eloquent(Theme::with(array('user' => function ($q) {
    $q->addSelect(array('id','username'))
}))->get();

I just found this trick also works well with load() too. This is very convenient.

$queriedTheme->load(array('user'=>function($q){$q->addSelect(..)});

Make sure you also include target table's key otherwise it won't be able to find it.

Solution 9 - Php

This Way:

Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->get();

Solution 10 - Php

I know that this is an old question, but if you are building an API, as the author of the question does, use output transformers to perform such tasks.

Transofrmer is a layer between your actual database query result and a controller. It allows to easily control and modify what is going to be output to a user or an API consumer.

I recommend Fractal as a solid foundation of your output transformation layer. You can read the documentation here.

Solution 11 - Php

In Laravel 4 you can hide certain fields from being returned by adding the following in your model.

protected $hidden = array('password','secret_field');

http://laravel.com/docs/eloquent#converting-to-arrays-or-json

Solution 12 - Php

On Laravel 5.5, the cleanest way to do this is:

Theme::with('user:userid,name,address')->get()

You add a colon and the fields you wish to select separated by a comma and without a space between them.

Solution 13 - Php

Using Model:

Model::where('column','value')->get(['column1','column2','column3',...]);

Using Query Builder:

DB::table('table_name')->where('column','value')->get(['column1','column2','column3',...]);

Solution 14 - Php

If I good understood this what is returned is fine except you want to see only one column. If so this below should be much simpler:

return Response::eloquent(Theme::with('user')->get(['username']));

Solution 15 - Php

#You can get selected columns from two or three different tables

$users= DB::Table('profiles')->select('users.name','users.status','users.avatar','users.phone','profiles.user_id','profiles.full_name','profiles.email','profiles.experience','profiles.gender','profiles.profession','profiles.dob',)->join('users','profiles.user_id','=','users.id')
            ->paginate(10);

Solution 16 - Php

Check out, http://laravel.com/docs/database/eloquent#to-array

You should be able to define which columns you do not want displayed in your api.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionraluView Question on Stackoverflow
Solution 1 - Phpuser2317976View Answer on Stackoverflow
Solution 2 - PhpJavi StolzView Answer on Stackoverflow
Solution 3 - PhpMelvinView Answer on Stackoverflow
Solution 4 - PhpaykutView Answer on Stackoverflow
Solution 5 - PhpSajjad AshrafView Answer on Stackoverflow
Solution 6 - PhpNufaylView Answer on Stackoverflow
Solution 7 - PhpJason LewisView Answer on Stackoverflow
Solution 8 - PhpKinoPView Answer on Stackoverflow
Solution 9 - PhpSpecsView Answer on Stackoverflow
Solution 10 - PhpArmen MarkossyanView Answer on Stackoverflow
Solution 11 - PhpJohn VeldboomView Answer on Stackoverflow
Solution 12 - PhpJoeGalindView Answer on Stackoverflow
Solution 13 - PhpMd. Saidur Rahman MilonView Answer on Stackoverflow
Solution 14 - PhpKornelView Answer on Stackoverflow
Solution 15 - PhpPradeep KumarView Answer on Stackoverflow
Solution 16 - PhpipixelsmediaworksView Answer on Stackoverflow