[英]How to get rid of too many if statements in laravel?
我想通过消除太多 if 语句来创建更具可读性的代码,但仍然可以完成这项工作。 我尝试创建一个私有方法并提取日期范围查询并返回构建器实例,但是每当我这样做时,它都不会返回正确的构建器查询结果,因此我最终在此方法上粉碎了所有内容。
其他参数将很快添加,因此 if 语句会很快堆积起来。 :(
任何关于如何改进的提示将不胜感激。 谢谢!
/**
* @param array $params
*
* @param $orderBy
* @param $sortBy
*
* @return Collection
*
* Sample:
* `/orders?release_date_start=2018-01-01&release_date_end=2018-02-20&firm_id=3` OR
* `/orders?claimId=3&status=completed`
*
* Problem: Too many if statements
*
*/
public function findOrdersBy(array $params, $orderBy = 'id', $sortBy = 'asc'): Collection
{
$release_date_start = array_get($params, 'release_date_start');
$release_date_end = array_get($params, 'release_date_end');
$claimId = array_get($params, 'claimId');
$firm_id = array_get($params, 'firm_id');
$status = array_get($params, 'status');
$orders = $this->model->newQuery();
if (!is_null($release_date_start) && !is_null($release_date_end)) {
$orders->whereBetween('releaseDate', [$release_date_start, $release_date_end]);
} else {
if (!is_null($release_date_start)) {
$orders->where('releaseDate', '>=', $release_date_start);
} else {
if (!is_null($release_date_end)) {
$orders->where('releaseDate', '<=', $release_date_end);
}
}
}
if (!is_null($claimId)) {
$orders->where(compact('claimId'));
}
if (!is_null($firm_id)) {
$orders->orWhere(compact('firm_id'));
}
if (!is_null($status)) {
$orders->where(compact('status'));
}
return $orders->orderBy($orderBy, $sortBy)->get();
}
如果您对使用集合方法感兴趣,那么您可以使用when()
集合方法来省略if-else
语句。 所以根据你的陈述,它看起来像:
$orders->when(!is_null($release_date_start) && !is_null($release_date_end), function($q) {
$q->whereBetween('releaseDate', [$release_date_start, $release_date_end]);
}, function($q) {
$q->when(!is_null($release_date_start), function($q) {
$q->where('releaseDate', '>=', $release_date_start);
}, function($q) {
$q->when(!is_null($release_date_end), function($q) {
$q->where('releaseDate', '<=', $release_date_end);
})
})
})
->when(!is_null($claimId), function($q) {
$q->where(compact('claimId'));
})
->when(!is_null($firm_id), function($q) {
$q->orWhere(compact('firm_id'));
})
->when(!is_null($status), function($q) {
$q->where(compact('status'));
})
有关更多信息,您可以查看文档中的条件子句。 希望这可以帮助。
您可以使用的一种选择是 php 中的三元运算,如下所示:
$claimId ? $orders->where(compact('claimId')) : ;
$firm_id ? $orders->orWhere(compact('firm_id')) : ;
$status ? $orders->where(compact('status')) : ;
它会比语句代码更干净。
您可以在 Laravel 中使用的另一个选项是条件子句
感谢您的建议,但我想出了另一个解决方案:
/**
* @param array $params
*
* @param $orderBy
* @param $sortBy
*
* @return Collection
*/
public function findOrdersBy(array $params, $orderBy = 'id', $sortBy = 'asc'): Collection
{
$release_date_start = array_get($params, 'release_date_start');
$release_date_end = array_get($params, 'release_date_end');
$orders = $this->model->newQuery();
if (!is_null($release_date_start) && !is_null($release_date_end)) {
$orders->whereBetween('releaseDate', [$release_date_start, $release_date_end]);
} else {
if (!is_null($release_date_start)) {
$orders->where('releaseDate', '>=', $release_date_start);
} else {
if (!is_null($release_date_end)) {
$orders->where('releaseDate', '<=', $release_date_end);
}
}
}
$fields = collect($params)->except($this->filtersArray())->all();
$orders = $this->includeQuery($orders, $fields);
return $orders->orderBy($orderBy, $sortBy)->get();
}
/**
* @param Builder $orderBuilder
* @param array $params
*
* @return Builder
*/
private function includeQuery(Builder $orderBuilder, ... $params) : Builder
{
$orders = [];
foreach ($params as $param) {
$orders = $orderBuilder->where($param);
}
return $orders;
}
/**
* @return array
*/
private function filtersArray() : array
{
return [
'release_date_start',
'release_date_end',
'order_by',
'sort_by',
'includes'
];
}
private method includeQuery(Builder $orderBuilder, ... $params)
的主要因素private method includeQuery(Builder $orderBuilder, ... $params)
将$params
作为可变长度参数。 我们只是迭代作为查询参数传递的变量/orders?code=123&something=test
并将它们作为查询构建器中的where()
子句传递。
某些参数可能不是您对象的属性,因此我们必须仅过滤与对象属性匹配的查询参数。 所以我创建了一个filtersArray()
来返回要排除的参数并防止错误。
嗯,实际上,在写这篇文章时,我应该有相反的东西only()
否则它将有无限的东西要排除。 :) 我猜这将是另一个重构。 :P
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.