我正在尝试扩展一个应用程序以使用我的新Laravel应用程序。在这种情况下,我得到的过滤器数量未知,我想将它们全部转发到where()
子句。
我做了这样的事情:
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;
}
问题是我得到了EQUALS
和CONTAINS
之类的运算符,因此我需要将它们转换为=
和LIKE
。
使用此代码,我正在尝试这样做:
return response(MyModel::where($filter)->get());
但是它不起作用。有解决这个问题的优雅方法吗?
编辑/解决方案
很抱歉@HCK,因为我不能完全接受答案,因为它不能回答我的问题,但这为我指明了正确的方向。解决方案是在数组中使用key
,operator
,value
键,而不要使用我的“无键”键。
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;
}
答案 0 :(得分:0)
您可以按照这种方式
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();
您还可以使用范围函数Ref
Exp-3 Laravel范围
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();
答案 1 :(得分:0)
不是解决问题的最好方法,但这应该可行:
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(); // <---
}
在这里,我正在使用Map()
类的Collection函数。此类提供了lot of useful methods。