acacha / users

User managment with Laravel and adminlte-laravel
MIT License
2 stars 0 forks source link

Implement filter on API #5

Open acacha opened 7 years ago

acacha commented 7 years ago

Vue-table filter-bar requires API filtering when a query string filter exists.

https://github.com/ratiw/vue-table/wiki/Appending-Other-Parameters-to-the-Query-String

https://github.com/ratiw/vuetable-sample-api-endpoint

acacha commented 7 years ago

https://github.com/ratiw/vuetable-sample-api-endpoint/blob/master/app/Http/routes.php

if ($request->exists('filter')) {
        $query->where(function($q) use($request) {
            $value = "%{$request->filter}%";
            $q->where('name', 'like', $value)
                ->orWhere('nickname', 'like', $value)
                ->orWhere('email', 'like', $value);
        });
    }
acacha commented 7 years ago

https://laracasts.com/discuss/channels/general-discussion/how-to-create-a-laravel-restful-api-allowing-requests-with-url-params?page=1

trait FilterableTrait
{

    protected $validFilterableFields = [];

    protected $filters = [];

    protected function addFilter($field, $value)
    {
        if(!in_array($field, $this->validFilterableFields)) {
            return false;
        }
        $filterMethod = 'filterBy' . camel_case($field);
        if( method_exists( $this, $filterMethod ) ) {
            $this->$filterMethod($value);
        } else {
            $this->filters[$field] = $value;
        }
        return true;
    }

    protected function applyFiltersToQuery($query)
    {
        foreach($this->filters as $field => $value) {
            $query->where($field, $value);
        }
        return $query;
    }
}

Typically, I'd add it to a repository and use that to do the filtering:

//not ripped from a current project, sadly :'(
class EloquentAvengersRepository extends EloquentRepository implements AvengersRepository
{
    use FilterableTrait;

    $this->validFilterableFields = ['is_genius', 'owns_hammer', 'loves_freedom', 'unpopular_when_angry'];

    public function filterBy($field, $value)
    {
        $this->addFilter($field, $value);
        return $this;
    }

    public function all()
    {
        return $this->applyFiltersToQuery( $this->query() )->paginate(10);
    }

}

So now I can use the repository like so:

$this->avengersRepo->filterBy($foo, $bar)->all();