Add lists() method in Query Builder in Laravel 5.4

Ateeq Ahmed   picture Ateeq Ahmed · Apr 13, 2017 · Viewed 8.7k times · Source


I know the fact that Laravel has removed lists() function and moved functions signature as pluck(). But, this leads to a lot of work for someone who wants to Upgrade from Laravel 4.x to Laravel 5.4.

Hence, I am trying to find a way to just make use of existing function i.e. lists() in my code and just make use of pluck()->toArray() when this function is called.


I have tried the following.

Method 1

class BaseModel extends  Illuminate\Database\Query\Builder
public function __call($method, $args)
{
    return call_user_func_array($this->method,$args);
}

public function lists($column){
return $this->pluck($column)->toArray();
}

Wont work!.
Reason : This needs to be extended along with the BaseModel class. But, it already extends Eloquent Model Class.

Method 2

Tried adding the Required function using trait like

listsWorkAround.php

<?php
trait listsWorkAround
{ 
  function lists($column){
    return $this->pluck($column)->toArray();
  }
}

Model.php

<?php
namespace App;

use Watson\Rememberable\Rememberable;
use Illuminate\Database\Eloquent\Model as Eloquent;

abstract class Model extends Eloquent
{
    use listsWorkAround;
    use Rememberable;
}

Nope ain't no success.

Method 3

Tried adding a as ServiceProvider and add a macro function for the Builder Class i.e. lists in this case.
But, the problem is the final returned entity is a Collection no matter what as it is returned using the __call function of the Builder. But, the desired entity is an Array.

Edit : The Code I used for Method 3

<?php
namespace Providers;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\ServiceProvider;

class ListsWorkAround extends ServiceProvider
{
    /**
     * {@inheritdoc}
     */
    public function register()
    {
        Builder::macro("lists", function ($column) {        
            return $this->pluck($column)->toArray();
        });
    }
}

But, as I said this would still return Collection.

Answer

Ateeq Ahmed   picture Ateeq Ahmed · Apr 14, 2017

So, this is what I ended up doing to make it work i.e. lists() in Model::XXX->lists()

Added this in ..../config/app.php

'providers' => [
 ...
 ...
 \App\Providers\ListsWorkAround::class,
],

and this is Provider Class File.

ListsWorkAround.php

<?php
/**
 * Created by PhpStorm.
 * User: ateeq-ahmed
 * Date: 14/4/17
 * Time: 11:25 AM
 */

namespace App\Providers;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Support\ServiceProvider;

class ListsWorkAround extends ServiceProvider
{
    /**
     * {@inheritdoc}
     */
    public function register()
    {
        Builder::macro("lists", function ($column, $key = null) {
            return $this->pluck($column, $key)->all();
        });

        QueryBuilder::macro("lists", function ($column, $key = null) {
            return $this->pluck($column, $key)->all();
        });
    }
}