specialtactics / laravel-api-boilerplate

Laravel API Boilerplate | Quickly build quality API products!
MIT License
490 stars 94 forks source link

Question about filtering/sorting #50

Closed nguyenpr9 closed 3 years ago

nguyenpr9 commented 3 years ago

How can i filter,sort? Any doc,wiki for this?

heidbyte commented 3 years ago

Same problem for me

specialtactics commented 3 years ago

Hey

There's a number of third party packages that you can use for this, personally, I use https://github.com/Tucker-Eric/EloquentFilter and there is also a spatie one. Both of these I plan to integrate more deeply into the boilerplate, but there's actually no reason you can't just use it normally.

kfoon commented 3 years ago

I try to add this function for the RestfulController

public function getAllWithFilter(Request $request) { $this->authorizeUserAction('viewAll');

    $model = new static::$model;

    // If we are caching the endpont, do a simple get all resources
    if (static::$cacheAll) {
        return $this->response->collection(Cache::remember(static::getCacheKey(), static::$cacheExpiresIn, function () use ($model) {
            return $model::with($model::getCollectionWith())->get();
        }), $this->getTransformer());
    }

   $data = $request->except('token','page','per_page');
   $query = $model::with($model::getCollectionWith());

    foreach ($data as $key => $item) {
        $query->where($key,$item)->toSql();
    }

    $this->qualifyCollectionQuery($query);

    // Handle pagination, if applicable
    $perPage = $model->getPerPage();
    if ($perPage) {
        // If specified, use per_page of the request
        if (request()->has('per_page')) {
            $perPage = intval(request()->input('per_page'));
        }

        $paginator = $query->paginate($perPage);

        return $this->response->paginator($paginator, $this->getTransformer());
    } else {
        $resources = $query.$test->get();

        return $this->response->collection($resources, $this->getTransformer());
    }
}

I pass params on the get url call

kfoon commented 3 years ago

i will try to add an if for the date between and see how it comes out

specialtactics commented 3 years ago

What we do in our projects at the moment is just use eloquent filter which does all of this type of stuff. The integration between that package and the boilerplate is super simple, and all you need to do is add this in the controller for the relevant mode/endpoint:

    public function qualifyCollectionQuery($query)
    {
        return parent::qualifyCollectionQuery($query)->filter(request()->all());
    }

Then you can add whatever filtering and other logic you like in the model's filter class as per eloquentfilter docs.

kfoon commented 3 years ago

This is the error i have when i add this to the contorller:

"message" => "Call to undefined method Specialtactics\L5Api\Models\Builder::filter()" "statusCode" => 500

specialtactics commented 3 years ago

You need to actually install eloquentfilter and set it up on the model first though.

kfoon commented 3 years ago

finally got my function working with the date between:

so the request should be like:

$params = ['per_page' => 500, 'page' => 1, 'status' => $request->status, 'created_at' => "2021-03-18,2021-03-18"];

`public function getAllWithFilter(Request $request) { $this->authorizeUserAction('viewAll');

    $model = new static::$model;

    // If we are caching the endpont, do a simple get all resources
    if (static::$cacheAll) {
        return $this->response->collection(Cache::remember(static::getCacheKey(), static::$cacheExpiresIn, function () use ($model) {
            return $model::with($model::getCollectionWith())->get();
        }), $this->getTransformer());
    }

    //search fiels for between
   $between = array('created_at', 'updated_at','start_date','end_date','deleted_at');
   $data = $request->except('token','page','per_page');
   $query = $model::with($model::getCollectionWith());

    foreach ($data as $key => $item) {
        if(in_array($key,$between)){
        //$dates[$key] = $item;
        $dates = explode(',', $item);
        $query->whereBetween($key, [$dates[0].' 00:00:00', $dates[1].' 23:59:59'])->toSql();
        }else{
        $query->where($key,$item)->toSql();
        }
    }

    $this->qualifyCollectionQuery($query);

    // Handle pagination, if applicable
    $perPage = $model->getPerPage();
    if ($perPage) {
        // If specified, use per_page of the request
        if (request()->has('per_page')) {
            $perPage = intval(request()->input('per_page'));
        }

        $paginator = $query->paginate($perPage);

        return $this->response->paginator($paginator, $this->getTransformer());
    } else {
        $resources = $query.$test->get();

        return $this->response->collection($resources, $this->getTransformer());
    }
}`