I am trying to extend one app to use my new Laravel app. In this scenario I am getting an unknown number of filters and I would like to forward them all to where()
clause.
I have made something like this:
private function filterConverter($filter)
{
$f = [];
foreach ($filter as $singleFilter) {
$operator = $this->filterValues[$singleFilter['operator']];
$value = $operator == 'like' ? '%' . $singleFilter['value'] . '%' : $singleFilter['value'];
$f[] = $singleFilter['field'] . ',' . $operator . ',' . $value;
}
return $f;
}
The thing is that I am getting operators like EQUALS
and CONTAINS
so I need to convert them to =
and LIKE
.
With this code I am trying to do this:
return response(MyModel::where($filter)->get());
But it doesn't work. Is there any elegant way to resolve this?
EDIT/SOLUTION
Sorry to @HCK as I couldn't quite accept the answer since it doesn't answer my question, but it pointed me on the right track. The solution was to use key
, operator
, value
keys in the array instead of what I had "keyless".
private function filterConverter($filters)
{
$filter = [];
foreach ($filters as $singleFilter) {
$operator = $this->filterMap[$singleFilter['operator']];
$value = $operator == 'LIKE' ? '%' . $singleFilter['value'] . '%' : $singleFilter['value'];
$filter[] = [
'key' => $singleFilter['field'],
'operator' => $operator,
'value' => $value
];
}
return $filter;
}
You may follow this way
DB::table('users')
->where(function($query) use ($filter)
{
// You able to access $filter here
// You may able to to generate this block by loop
$query->where('votes', '>', 100)
->where('title', '<>', 'Admin');
})
->get();
Exp-1
$filters = [
['key' => 'votes', 'operator' => '>', 'value' => 100]
];
DB::table('users')
->where(function ($query) use ($filters) {
foreach ($filters as $filter) {
if (@$filter['key'] && @$filter['operator'] && @$filter['value']) {
$query->where($filter['key'], $filter['operator'], $filter['value']);
}
}
})->get();
Exp-2
$filters = [
['key' => 'votes', 'operator' => '>', 'value' => 100]
];
DB::table('users')
->where(function ($query) use ($filters) {
foreach ($filters as $filter) {
if (@$filter['key'] && @$filter['operator'] && @$filter['value']) {
$query->whereRaw("{$filter['key']} {$filter['operator']} '{$filter['value']}'");
}
}
})->get();
You may also use scope function Ref
Exp-3 Laravel Scope
class User extends Model
{
public function scopeFilter($query, $filters)
{
foreach ($filters as $filter) {
if (@$filter['key'] && @$filter['value']) {
$query->where($filter['key'], @$filter['operator']?:"=", $filter['value']);
}
}
return $query;
}
}
// Use
User::filter($filters)->get();
Not the nicest way to solve it, but this should work:
private function filterConverter($filters)
{
return collect($filters)->map(function ($filter) { // <---
if($filter['operator'] == 'CONTAINS')
{
$filter['value'] = '%' . $filter['value'] . '%';
$filter['operator'] = 'LIKE';
}
else if ($filter['operator'] == 'EQUALS')
{
$filter['operator'] = '=';
}
return collect($filter)->flatten(); // <---
})->toArray(); // <---
}
Here I'm using the Map()
function of the Collection class. there is a lot of useful methods provided by this class.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.