Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Items filter laravel eloquent

What is the best way to implement the items filter functionality?

I have a table with some items, and each item has some fields.

How can I select items with fields filtering, like e-commerce filtering, using Laravel 5 and Eloquent?

like image 852
aGoodRussianGuy Avatar asked Jul 08 '16 17:07

aGoodRussianGuy


People also ask

How do you filter eloquent?

You can filter some of the request params for use in Eloquent Filter. User::AcceptRequest(['username','id']) ->filter() ->paginate(request()->get('perpage'), ['*'], 'page');

What is filter in Laravel?

The filter query parameters can be used to add where clauses to your Eloquent query. Out of the box we support filtering results by partial attribute value, exact attribute value or even if an attribute value exists in a given array of values. For anything more advanced, custom filters can be used.

What is the use of pluck in Laravel?

Laravel Pluck() is a Laravel Collections method used to extract certain values from the collection. You might often would want to extract certain data from the collection i.e Eloquent collection.

What is chunk in Laravel?

If your database table has lots of data, chunk() method is the best to use. The chunk() method can be used on the DB facade and also on Eloquent models. The chunk() takes care of fetching a small amount of data at a time and the result is present inside the closure for processing.


2 Answers

I've always used eloquent scopes to filter eloquent results: https://laravel.com/docs/5.1/eloquent#query-scopes

Your Controller:

use App\Item;

class ItemController extends Controller
{
    public function index(Request $request)
    {
        $items = Item::name($request->name)->price($request->price)->paginate(25);

        return view('items.index', compact('items'));
    }
}

Your Model:

class Item extends Model
{
    public function scopeName($query, $name)
    {
        if (!is_null($name)) {
            return $query->where('name', 'like', '%'.$name.'%');
        }

        return $query;
    }

    public function scopePrice($query, $price)
    {
        if (!is_null($price)) {
            return $query->where(compact('price'));
        }

        return $query;
    }
}

Your View:

<form action="{{ route('items.index') }}" method="get">
    <input type="text" name="price" />
    <input type="text" name="name" />
    <input type="submit" value="Search">
</form>

@foreach($items as $item)
    {{ $item->name }}
@endforeach

{!! $items->render() !!}

In your scopes, you can check if the given value is null before limiting your query results. This effectively allows users to search and filter paginated results.

You could further enhance the search by automatic validation using Laravel's Form Requests so you can sure that the input they are searching for matches the data type for your query.

Keep in mind you'll have to modify the getRedirectUrl() method since your users will be executing a GET request and by default the getRedirectUrl() will contain the GET URL parameters resulting in an infinite loop since the one of the params failed validation.

Here's an example using the above:

class ItemSearchRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'nullable|string|min:2|max:100',
            'price' => 'nullable|numeric',
        ];
    }

    protected function getRedirectUrl()
    {
        return url('/items');
    }
}
like image 98
Steve Bauman Avatar answered Oct 21 '22 13:10

Steve Bauman


I wrote a package for exactly this here: https://github.com/Tucker-Eric/EloquentFilter

It allows you to do something like:

use App\Item;

class ItemController extends Controller
{
    public function index(Request $request)
    {
        $items = Item::filter($request->all())->paginateFilter(25);

        return view('items.index', compact('items'));
    }
}
like image 34
Eric Tucker Avatar answered Oct 21 '22 15:10

Eric Tucker