Skip to content
Closed
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
51 changes: 19 additions & 32 deletions src/Illuminate/Database/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,30 @@ public function get($columns = array('*'))
}

/**
* Pluck a single column from the database.
* Get an array with the values of a given column.
*
* @param string $column
* @return mixed
* @param string $key
* @return array
*/
public function pluck($column)
public function pluck($column, $key = null)
{
$result = $this->first(array($column));
$results = $this->query->pluck($column, $key);

if ($result) return $result->{$column};
// If the model has a mutator for the requested column, we will spin through
// the results and mutate the values so that the mutated version of these
// columns are returned as you would expect from these Eloquent models.
if ($this->model->hasGetMutator($column))
{
foreach ($results as $key => &$value)
{
$fill = array($column => $value);

$value = $this->model->newFromBuilder($fill)->$column;
}
}

return $results;
}

/**
Expand Down Expand Up @@ -212,33 +226,6 @@ public function chunk($count, callable $callback)
}
}

/**
* Get an array with the values of a given column.
*
* @param string $column
* @param string $key
* @return array
*/
public function lists($column, $key = null)
{
$results = $this->query->lists($column, $key);

// If the model has a mutator for the requested column, we will spin through
// the results and mutate the values so that the mutated version of these
// columns are returned as you would expect from these Eloquent models.
if ($this->model->hasGetMutator($column))
{
foreach ($results as $key => &$value)
{
$fill = array($column => $value);

$value = $this->model->newFromBuilder($fill)->$column;
}
}

return $results;
}

/**
* Get a paginator for the "select" statement.
*
Expand Down
4 changes: 2 additions & 2 deletions src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ public function getRelatedIds()

$fullKey = $related->getQualifiedKeyName();

return $this->getQuery()->select($fullKey)->lists($related->getKeyName());
return $this->getQuery()->select($fullKey)->pluck($related->getKeyName());
}

/**
Expand Down Expand Up @@ -596,7 +596,7 @@ public function sync($ids, $detaching = true)
// First we need to attach any of the associated models that are not currently
// in this joining table. We'll spin through the given IDs, checking to see
// if they exist in the array of current ones, and if not we will insert.
$current = $this->newPivotQuery()->lists($this->otherKey);
$current = $this->newPivotQuery()->pluck($this->otherKey);

$records = $this->formatSyncList($ids);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function __construct(Resolver $resolver, $table)
*/
public function getRan()
{
return $this->table()->lists('migration');
return $this->table()->pluck('migration');
}

/**
Expand Down
63 changes: 25 additions & 38 deletions src/Illuminate/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1348,16 +1348,34 @@ public function find($id, $columns = array('*'))
}

/**
* Pluck a single column's value from the first result of a query.
* Get an array with the values of a given column.
*
* @param string $column
* @return mixed
* @param string $key
* @return array
*/
public function pluck($column)
public function pluck($column, $key = null)
{
$result = (array) $this->first(array($column));
$columns = $this->getListSelect($column, $key);

return count($result) > 0 ? reset($result) : null;
// First we will just get all of the column values for the record result set
// then we can associate those values with the column if it was specified
// otherwise we can just give these values back without a specific key.
$results = new Collection($this->get($columns));

$values = $results->fetch($columns[0])->all();

// If a key was specified and we have results, we will go ahead and combine
// the values with the keys of all of the records so that the values can
// be accessed by the key of the rows instead of simply being numeric.
if ( ! is_null($key) && count($results) > 0)
{
$keys = $results->fetch($key)->all();

return array_combine($keys, $values);
}

return $values;
}

/**
Expand Down Expand Up @@ -1629,37 +1647,6 @@ private function defaultKeyName(): string
return 'id';
}

/**
* Get an array with the values of a given column.
*
* @param string $column
* @param string $key
* @return array
*/
public function lists($column, $key = null)
{
$columns = $this->getListSelect($column, $key);

// First we will just get all of the column values for the record result set
// then we can associate those values with the column if it was specified
// otherwise we can just give these values back without a specific key.
$results = new Collection($this->get($columns));

$values = $results->fetch($columns[0])->all();

// If a key was specified and we have results, we will go ahead and combine
// the values with the keys of all of the records so that the values can
// be accessed by the key of the rows instead of simply being numeric.
if ( ! is_null($key) && count($results) > 0)
{
$keys = $results->fetch($key)->all();

return array_combine($keys, $values);
}

return $values;
}

/**
* Get the columns that should be used in a list array.
*
Expand Down Expand Up @@ -1691,9 +1678,9 @@ protected function getListSelect($column, $key)
*/
public function implode($column, $glue = null)
{
if (is_null($glue)) return implode($this->lists($column));
if (is_null($glue)) return implode($this->pluck($column));

return implode($glue, $this->lists($column));
return implode($glue, $this->pluck($column));
}

/**
Expand Down
12 changes: 6 additions & 6 deletions tests/Database/DatabaseEloquentBelongsToManyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ public function testSyncMethodSyncsIntermediateTableWithGivenArray($list)
$query->shouldReceive('where')->once()->with('user_id', 1)->andReturn($query);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock('StdClass'));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$query->shouldReceive('lists')->once()->with('role_id')->andReturn([1, 2, 3]);
$query->shouldReceive('pluck')->once()->with('role_id')->andReturn([1, 2, 3]);
$relation->expects($this->once())->method('attach')->with($this->equalTo(4), $this->equalTo([]), $this->equalTo(false));
$relation->expects($this->once())->method('detach')->with($this->equalTo([1]));
$relation->getRelated()->shouldReceive('touches')->andReturn(false);
Expand All @@ -330,7 +330,7 @@ public function testSyncMethodSyncsIntermediateTableWithGivenArrayAndAttributes(
$query->shouldReceive('where')->once()->with('user_id', 1)->andReturn($query);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock('StdClass'));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$query->shouldReceive('lists')->once()->with('role_id')->andReturn([1, 2, 3]);
$query->shouldReceive('pluck')->once()->with('role_id')->andReturn([1, 2, 3]);
$relation->expects($this->once())->method('attach')->with($this->equalTo(4), $this->equalTo(['foo' => 'bar']), $this->equalTo(false));
$relation->expects($this->once())->method('updateExistingPivot')->with($this->equalTo(3), $this->equalTo(
['baz' => 'qux']
Expand All @@ -355,7 +355,7 @@ public function testSyncMethodDoesntReturnValuesThatWereNotUpdated()
$query->shouldReceive('where')->once()->with('user_id', 1)->andReturn($query);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock('StdClass'));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$query->shouldReceive('lists')->once()->with('role_id')->andReturn([1, 2, 3]);
$query->shouldReceive('pluck')->once()->with('role_id')->andReturn([1, 2, 3]);
$relation->expects($this->once())->method('attach')->with($this->equalTo(4), $this->equalTo(['foo' => 'bar']), $this->equalTo(false));
$relation->expects($this->once())->method('updateExistingPivot')->with($this->equalTo(3), $this->equalTo(
['baz' => 'qux']
Expand All @@ -380,7 +380,7 @@ public function testTouchMethodSyncsTimestamps()
$relation->getRelated()->shouldReceive('freshTimestamp')->andReturn($carbon);
$relation->getRelated()->shouldReceive('getQualifiedKeyName')->andReturn('table.id');
$relation->getQuery()->shouldReceive('select')->once()->with('table.id')->andReturn($relation->getQuery());
$relation->getQuery()->shouldReceive('lists')->once()->with('id')->andReturn([1, 2, 3]);
$relation->getQuery()->shouldReceive('pluck')->once()->with('id')->andReturn([1, 2, 3]);
$relation->getRelated()->shouldReceive('newQuery')->once()->andReturn($query = m::mock(Builder::class));
$query->shouldReceive('whereIn')->once()->with('id', [1, 2, 3])->andReturn($query);
$query->shouldReceive('update')->once()->with(['updated_at' => $carbon]);
Expand Down Expand Up @@ -409,7 +409,7 @@ public function testSyncMethodConvertsCollectionToArrayOfKeys()
$query->shouldReceive('where')->once()->with('user_id', 1)->andReturn($query);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock('StdClass'));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$query->shouldReceive('lists')->once()->with('role_id')->andReturn([1, 2, 3]);
$query->shouldReceive('pluck')->once()->with('role_id')->andReturn([1, 2, 3]);

$collection = m::mock(Collection::class);
$collection->shouldReceive('modelKeys')->once()->andReturn([1, 2, 3]);
Expand Down Expand Up @@ -443,7 +443,7 @@ public function testWherePivotParamsUsedForNewQueries()
$query->shouldReceive('where')->once()->with('foo', '=', 'bar')->andReturn($query);

// This is so $relation->sync() works
$query->shouldReceive('lists')->once()->with('role_id')->andReturn([1, 2, 3]);
$query->shouldReceive('pluck')->once()->with('role_id')->andReturn([1, 2, 3]);
$relation->expects($this->once())->method('formatSyncList')->with([1, 2, 3])->willReturn(
[1 => [], 2 => [], 3 => []]
);
Expand Down
30 changes: 5 additions & 25 deletions tests/Database/DatabaseEloquentBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,27 +137,7 @@ public function testGetMethodDoesntHydrateEagerRelationsWhenNoResultsAreReturned
}


public function testPluckMethodWithModelFound()
{
$builder = m::mock('Illuminate\Database\Eloquent\Builder[first]', [$this->getMockQueryBuilder()]);
$mockModel = new StdClass;
$mockModel->name = 'foo';
$builder->shouldReceive('first')->with(['name'])->andReturn($mockModel);

$this->assertEquals('foo', $builder->pluck('name'));
}


public function testPluckMethodWithModelNotFound()
{
$builder = m::mock('Illuminate\Database\Eloquent\Builder[first]', [$this->getMockQueryBuilder()]);
$builder->shouldReceive('first')->with(['name'])->andReturn(null);

$this->assertNull($builder->pluck('name'));
}


public function testValueMethodWithModelFound()
public function testValueMethodWithModelFound()
{
$builder = m::mock('Illuminate\Database\Eloquent\Builder[first]', [$this->getMockQueryBuilder()]);
$mockModel = new StdClass;
Expand Down Expand Up @@ -201,7 +181,7 @@ public function testChunkExecuteCallbackOverPaginatedRequest()
public function testListsReturnsTheMutatedAttributesOfAModel()
{
$builder = $this->getBuilder();
$builder->getQuery()->shouldReceive('lists')->with('name', '')->andReturn(['bar', 'baz']);
$builder->getQuery()->shouldReceive('pluck')->with('name', '')->andReturn(['bar', 'baz']);
$builder->setModel($this->getMockModel());
$builder->getModel()->shouldReceive('hasGetMutator')->with('name')->andReturn(true);
$builder->getModel()->shouldReceive('newFromBuilder')->with(['name' => 'bar'])->andReturn(new EloquentBuilderTestListsStub(
Expand All @@ -211,18 +191,18 @@ public function testListsReturnsTheMutatedAttributesOfAModel()
['name' => 'baz']
));

$this->assertEquals(['foo_bar', 'foo_baz'], $builder->lists('name'));
$this->assertEquals(['foo_bar', 'foo_baz'], $builder->pluck('name'));
}


public function testListsWithoutModelGetterJustReturnTheAttributesFoundInDatabase()
{
$builder = $this->getBuilder();
$builder->getQuery()->shouldReceive('lists')->with('name', '')->andReturn(['bar', 'baz']);
$builder->getQuery()->shouldReceive('pluck')->with('name', '')->andReturn(['bar', 'baz']);
$builder->setModel($this->getMockModel());
$builder->getModel()->shouldReceive('hasGetMutator')->with('name')->andReturn(false);

$this->assertEquals(['bar', 'baz'], $builder->lists('name'));
$this->assertEquals(['bar', 'baz'], $builder->pluck('name'));
}


Expand Down
2 changes: 1 addition & 1 deletion tests/Database/DatabaseMigrationRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function testGetRanMigrationsListMigrationsByPackage()
$connectionMock = m::mock(Connection::class);
$repo->getConnectionResolver()->shouldReceive('connection')->with(null)->andReturn($connectionMock);
$repo->getConnection()->shouldReceive('table')->once()->with('migrations')->andReturn($query);
$query->shouldReceive('lists')->once()->with('migration')->andReturn('bar');
$query->shouldReceive('pluck')->once()->with('migration')->andReturn('bar');

$this->assertEquals('bar', $repo->getRan());
}
Expand Down
19 changes: 3 additions & 16 deletions tests/Database/DatabaseQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ public function testListMethodsGetsArrayOfColumnValues(): void
{
return $results;
});
$results = $builder->from('users')->where('id', '=', 1)->lists('foo');
$results = $builder->from('users')->where('id', '=', 1)->pluck('foo');
$this->assertEquals(['bar', 'baz'], $results);

$builder = $this->getBuilder();
Expand All @@ -762,7 +762,7 @@ public function testListMethodsGetsArrayOfColumnValues(): void
{
return $results;
});
$results = $builder->from('users')->where('id', '=', 1)->lists('foo', 'id');
$results = $builder->from('users')->where('id', '=', 1)->pluck('foo', 'id');
$this->assertEquals([1 => 'bar', 10 => 'baz'], $results);
}

Expand Down Expand Up @@ -871,20 +871,7 @@ public function testQuickPaginateCorrectlyCreatesPaginatorInstance(): void
}


public function testPluckMethodReturnsSingleColumn(): void
{
$builder = $this->getBuilder();
$builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ? limit 1', [1]
)->andReturn([['foo' => 'bar']]);
$builder->getProcessor()->shouldReceive('processSelect')->once()->with($builder, [['foo' => 'bar']])->andReturn(
[['foo' => 'bar']]
);
$results = $builder->from('users')->where('id', '=', 1)->pluck('foo');
$this->assertEquals('bar', $results);
}


public function testValueMethodReturnsSingleColumn(): void
public function testValueMethodReturnsSingleColumn(): void
{
$builder = $this->getBuilder();
$builder->getConnection()->shouldReceive('select')->once()->with('select "foo" from "users" where "id" = ? limit 1', [1]
Expand Down
Loading