Quando inizi ad applicare le condizioni alle tue query, devi prendere nota della seguente funzione:newQuery()
. Questa funzione ti consentirà di avviare un nuovo generatore di query e di concatenare i tuoi filtri/ordinazioni su di esso.
Esempio di schema:
Colonne in Prodotto tabella:
id | name | price | date_received
Colonne in tag_prodotto tabella:
id | tag_id | product_id
Colonna in tag tabella:
id | name
Relazione:
- Molti prodotti hanno molti tag
Non imposterò i modelli eloquenti, anche se tieni presente che il modello del prodotto ha un tag()
funzione con un hasManyThrough()
relazione
È stata impostata una classe di filtri con lo scopo principale di applicare i filtri e ordinare per. Nota:la classe può essere ulteriormente astratta.
La tua classe di filtri:
class ProductFilter {
/**
* Fluent query builder
* @var mixed $queryBuilder
*/
private $queryBuilder;
/**
* Http Request
* @var \Illuminate\Http\Request $request
*/
protected $request;
/**
* Filters collection
* @var array $filters
*/
private $filters = [];
/**
* Order Bys Collection
* @var array $orderBys
*/
private $orderBys = [];
/**
* Class constructor
*
* @param array $input
*/
public function __construct(\Illuminate\Http\Request $request, &$queryBuilder)
{
//Initialize Query Builder
$this->queryBuilder = $queryBuilder;
//Get input
$this->request = $request;
//Register Filters
$this->registerFilters();
//Register Order Bys
$this->registerOrderBys();
}
/**
* Register Filters in the function below
* Each filter is in the form of an array
*/
private function registerFilters()
{
$this->filters['product_name'] = ['name'=>'Name',
'value' => $this->request->get('filter_product_name'),
'enabled' => $this->request->has('filter_product_name'),
'function' => 'filterProductName'
];
$this->filters['tag'] = ['name'=>'End Date',
'value' => $this->request->get('filter_tag'),
'enabled' => $this->request->has('filter_tag'),
'function' => 'filterTag'
];
}
/**
* Check if any filters are active
* Useful to show/hide filter bar
*
* @return bool
*/
public function isFiltersActive()
{
return (boolean)count(
array_filter($this->filters,function($v){
return $v['enabled'] === true;
})
);
}
/**
* Register Order Bys in the function below
* Each order by is in the form of an array
*
*/
private function registerOrderBys()
{
$this->orderBys['name'] = [
'name' => 'Order By Name',
'value' => $this->request->get('order_by_product_name','ASC'),
'enabled' => $this->request->has('order_by_product_name'),
'function' => 'orderByProductName'
];
}
/**
* Check if any order bys are active
* Useful to show/hide order by bar
*
* @return bool
*/
public function isOrderBysActive()
{
return (boolean)count(
array_filter($this->orderBys,function($v){
return $v['enabled'] === true;
})
);
}
/**
* Apply Filters
* Loop through each filter, check if they are enabled. If they are, apply filter to query builder
*/
public function applyFilters()
{
foreach($this->filters as $filter_name => $filter_array)
{
if($filter_array['enabled'] &&
array_key_exists('function',$filter_array) &&
method_exists($this,$filter_array['function']))
{
$this->{$filter_array['function']}($filter_array);
}
}
return $this;
}
/**
* Apply Order Bys
* Loop through each order by, check if they are enabled. If they are, apply order by to query builder
*/
public function applyFilters()
{
foreach($this->orderBys as $order_by_name => $order_by_array)
{
if($order_by_array['enabled'] &&
array_key_exists('function',$order_by_array) &&
method_exists($this,$order_by_array['function']))
{
$this->{$order_by_array['function']}($order_by_array);
}
}
return $this;
}
/*
* Filter Functions: START
*/
/**
* Filter by Product Name
*
* @param array $filterArray
*/
private function filterProductName($filterArray)
{
$this->queryBuilder
->where('name','=',$filterArray['value']);
}
/**
* Filter by Product Tag
*
* @param array $filterArray
*/
private function filterTag($filterArray)
{
$this->queryBuilder
->whereHas('tag',function($query) use ($filterArray){
return $query->where('name','=',$filterArray['value']);
});
}
/*
* Filter Functions: END
*/
/*
* Order By Functions: START
*/
/**
* Order By Name
* @param array $orderByArray
*/
private function orderByName($orderByArray)
{
$this->queryBuilder
->orderBy('name', $orderByArray['value']);
}
/*
* Order By Functions: END
*/
}
Come usare:
//In my controller function
public function getListOfProducts(\Illuminate\Http\Request $request)
{
//Init Product Query
$productQuery = \App\Models\Product()::newQuery();
//Apply all filters and order bys
$productFilter = app('ProductFilter',[$request,$productQuery])->applyFilters()->applyOrderBys();
//Fetch Product Result
$productResult = $productQuery->get();
}