Get only specific attributes with from Laravel Collection

use User::get(['id', 'name', 'email']), it will return you a collection with the specified columns and if you want to make it an array, just use toArray() after the get() method like so:

User::get(['id', 'name', 'email'])->toArray()

Most of the times, you won't need to convert the collection to an array because collections are actually arrays on steroids and you have easy-to-use methods to manipulate the collection.


  1. You need to define $hidden and $visible attributes. They'll be set global (that means always return all attributes from $visible array).

  2. Using method makeVisible($attribute) and makeHidden($attribute) you can dynamically change hidden and visible attributes. More: Eloquent: Serialization -> Temporarily Modifying Property Visibility


You can do this using a combination of existing Collection methods. It may be a little hard to follow at first, but it should be easy enough to break down.

// get your main collection with all the attributes...
$users = Users::get();

// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map(function ($user) {
    return collect($user->toArray())
        ->only(['id', 'name', 'email'])
        ->all();
});

Explanation

First, the map() method basically just iterates through the Collection, and passes each item in the Collection to the passed in callback. The value returned from each call of the callback builds the new Collection generated by the map() method.

collect($user->toArray()) is just building a new, temporary Collection out of the Users attributes.

->only(['id', 'name', 'email']) reduces the temporary Collection down to only those attributes specified.

->all() turns the temporary Collection back into a plain array.

Put it all together and you get "For each user in the users collection, return an array of just the id, name, and email attributes."


Laravel 5.5 update

Laravel 5.5 added an only method on the Model, which basically does the same thing as the collect($user->toArray())->only([...])->all(), so this can be slightly simplified in 5.5+ to:

// get your main collection with all the attributes...
$users = Users::get();

// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map(function ($user) {
    return $user->only(['id', 'name', 'email']);
});

If you combine this with the "higher order messaging" for collections introduced in Laravel 5.4, it can be simplified even further:

// get your main collection with all the attributes...
$users = Users::get();

// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map->only(['id', 'name', 'email']);

Method below also works.

$users = User::all()->map(function ($user) {
  return collect($user)->only(['id', 'name', 'email']);
});

Tags:

Php

Laravel