Pluck together with first using Query builder

2019-02-17 18:42发布

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

4条回答
Root(大扎)
2楼-- · 2019-02-17 18:53

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.

查看更多
Luminary・发光体
3楼-- · 2019-02-17 19:07

In Laravel 5.1+, 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;
}
查看更多
乱世女痞
4楼-- · 2019-02-17 19:12

Try this one:

$user =  User::pluck('name')->first();
echo $user;
查看更多
贼婆χ
5楼-- · 2019-02-17 19:19

Current alternative for pluck() is value().

To get first occurence, You can either use

  DB::table('users')->value('name');

or use,

 DB::table('users')->pluck('name')->first();
查看更多
登录 后发表回答