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?
You can filter some of the request params for use in Eloquent Filter. User::AcceptRequest(['username','id']) ->filter() ->paginate(request()->get('perpage'), ['*'], 'page');
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.
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.
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.
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');
}
}
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'));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With