Home » Php » Pluck together with first using Query builder

Pluck together with first using Query builder

Posted by: admin November 29, 2017 Leave a comment

Questions:

If I want to get get name of first user in database using eloquent I can do something like that:

$user =  User::select('name')->first()->pluck('name');
// or $user =  User::first()->pluck('name');

echo $user;

to get only name of this user as string.

However If I try the same using only query builder:

$user =  DB::table('users')->select('name')->first()->pluck('name');

echo $user;

I get exception:

Call to undefined method stdClass::pluck()

But without using first it will work:

$user =  DB::table('users')->select('name')->where('id',1)->pluck('name');

echo $user;

Is it not possible to use pluck with first using query builder or am I doing something wrong?

PS. Of course I know that I can display any property using $user->name without using pluck but I’m just curious why using Eloquent it works and using Query Builder it works only when not having both first and pluck

Answers:

You don’t want to use pluck with first, because it’s redundant:

$query->first() // fetch first row
      ->pluck('name'); // fetch first row again and return only name

So use only pluck:

$query->pluck('name');

It does all you need.


But there’s more.

Under the hood first and pluck run 2 separate queries, so:

$query->where(..)->orderBy(..)->first() // apply where and orderBy
        ->pluck('name'); // no where and orderBy applied here!

So it’s not only redundant to use first before pluck, but also it causes unexpected results.


You can chain those methods on Eloquent query, since it returns a collection (get) or model (first), but Query\Builder returns just an array (get) or stdObject (first). That’s why you couldn’t do the same oon the query builder.

Questions:
Answers:

Try this one:

$user =  User::pluck('name')->first();
echo $user;

Questions:
Answers:

You can use the value method.

From the docs:

If you don’t even need an entire row, you may extract a single value
from a record using the value method. This method will return the
value of the column directly:

$email = DB::table('users')->where('name', 'John')->value('email');

This is how it works behind the scenes in the Builder class:

/**
 * Get a single column's value from the first result of a query.
 *
 * @param  string  $column
 * @return mixed
 */
public function value($column)
{
    $result = (array) $this->first([$column]);
    return count($result) > 0 ? reset($result) : null;
}