Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 11 additions & 21 deletions src/Illuminate/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use InvalidArgumentException;
use Illuminate\Support\Collection;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Contracts\Support\Arrayable;
Expand Down Expand Up @@ -1538,23 +1537,24 @@ public function chunk($count, callable $callback)
* Get an array with the values of a given column.
*
* @param string $column
* @param string $key
* @param string|null $key
* @return array
*/
public function pluck($column, $key = null)
{
$columns = $this->getPluckSelect($column, $key);
$results = $this->get(func_get_args());

$results = new Collection($this->get($columns));

return $results->pluck($columns[0], Arr::get($columns, 1))->all();
// If the columns are qualified with a table or have an alias, we cannot use
// those directly in the "pluck" operation, since the results from the DB
// are only keyed by the column itself. We will strip everything else.
return Arr::pluck($results, $this->stripTable($column), $this->stripTable($key));
}

/**
* Alias for the "pluck" method.
*
* @param string $column
* @param string $key
* @param string|null $key
* @return array
*
* @deprecated since version 5.2. Use the "pluck" method directly.
Expand All @@ -1565,24 +1565,14 @@ public function lists($column, $key = null)
}

/**
* Get the columns that should be used in a pluck select.
* Strip off the table name or alias from a column identifier.
*
* @param string $column
* @param string $key
* @return array
* @return string|null
*/
protected function getPluckSelect($column, $key)
protected function stripTable($column)
{
$select = is_null($key) ? [$column] : [$column, $key];

// If the selected columns contain "dots", we will remove it so that the pluck
// operation can run normally. Specifying the table is not needed, since we
// really want the names of the columns as it is in this resulting array.
return array_map(function ($column) {
$dot = strpos($column, '.');

return $dot === false ? $column : substr($column, $dot + 1);
}, $select);
return is_null($column) ? $column : last(preg_split('~\.| ~', $column));
}

/**
Expand Down
16 changes: 16 additions & 0 deletions tests/Database/DatabaseEloquentIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function setUp()
{
$this->schema()->create('users', function ($table) {
$table->increments('id');
$table->string('name')->nullable();
$table->string('email')->unique();
$table->string('role')->default('standard');
$table->timestamps();
Expand Down Expand Up @@ -179,6 +180,21 @@ public function testPluck()
$this->assertEquals([1 => 'taylorotwell@gmail.com', 2 => 'abigailotwell@gmail.com'], $keyed);
}

public function testPluckWithJoin()
{
$user1 = EloquentTestUser::create(['id' => 1, 'name' => 'Taylor', 'email' => 'taylorotwell@gmail.com']);
$user2 = EloquentTestUser::create(['id' => 2, 'name' => 'Abigail', 'email' => 'abigailotwell@gmail.com']);

$user2->posts()->create(['id' => 1, 'name' => 'First post']);
$user1->posts()->create(['id' => 2, 'name' => 'Second post']);

$query = EloquentTestUser::join('posts', 'users.id', '=', 'posts.user_id');

$this->assertEquals([1 => 'First post', 2 => 'Second post'], $query->pluck('posts.name', 'posts.id')->all());
$this->assertEquals([2 => 'First post', 1 => 'Second post'], $query->pluck('posts.name', 'users.id')->all());
$this->assertEquals(['Abigail' => 'First post', 'Taylor' => 'Second post'], $query->pluck('posts.name', 'users.name as user_name')->all());
}

public function testFindOrFail()
{
EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);
Expand Down