Når du begynder at anvende betingelser på dine forespørgsler, skal du være opmærksom på følgende funktion:newQuery()
. Denne funktion giver dig mulighed for at starte en ny forespørgselsbygger og kæde dine filtre/ordrebys til den.
Eksempel på skema:
Kolonner i Produkt tabel:
id | name | price | date_received
Kolonner i product_tag tabel:
id | tag_id | product_id
Kolonne i tag tabel:
id | name
Forhold:
- Mange produkter har mange tags
Jeg vil ikke opsætte de veltalende modeller, men bemærk, at produktmodellen har et tag()
funktion med en hasManyThrough()
forhold
En filterklasse er blevet konfigureret med hovedformålet at anvende dine filtre og bestille bys. Bemærk:Klassen kan abstraheres endnu længere.
Din filterklasse:
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
*/
}
Sådan bruges:
//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();
}