我正在 Laravel 中制作一个存储库模式,我制作了一个
AbstractRepository
类,它可以由任何存储库扩展以获得最常用的可以共享的 CRUD 方法。
现在,如果我需要一些更复杂的查询,我可以通过向具体存储库添加额外的方法来扩展主要功能。
例如:
public function eagerWhere($column, $value, $relation, $orderBy = 'name')
{
return Region::with($relation)->where($column, $value)->orderBy($orderBy);
}
现在我遇到麻烦的部分是使用我的存储库的主要代码中的这一部分:
$regions = $this->regionRepository->eagerWhere('name', $term, 'country');
if ($includeCountry) { //<-- from here
$regions->orWhereHas('country', function ($query) use ($term) {
$query->where('name', 'LIKE', '%' . $term . '%');
});
}
如何在存储库中编写该部分,以便最终使它看起来像:
$regions = $this->regionRepository->eagerWhere('name', $term, 'country');
if ($includeCountry) {
$regions->orWhereHas($term, 'country');
}
我尝试将那部分代码复制到存储库,但后来我无法链接方法,因为当获取
$region
时,它不再被视为存储库实例,而是Eloquent
一个。现在它期待 Eloquent
方法。
我认为您的抽象级别有点复杂,因为您也没有抽象模型本身,但无论如何。解决方案可能是这样的:
public function eagerWhere($column, $value, $relation)
{
$builder = Region::with($relation)->where($column, $value);
return $builder
}
然后:
$regions = $this->regionRepository->eagerWhere('name', $term, 'country');
if ($includeCountry) {
$regions->orWhereHas($term, 'country');
}
return $regions->orderBy('name')->get();
我没能做到完全我想要的,但令人满意的解决方案是将完整的逻辑放在方法中,所以现在我有了这个:
public function eagerWhereLike($column, $value, $relation, $searchOnRelation = false, $orderBy = 'name')
{
$regions = Region::with($relation)->where($column, 'LIKE', '%' . $value . '%')->orderBy($orderBy);
if ($searchOnRelation) {
$regions->orWhereHas($relation, function ($query) use ($column, $value) {
$query->where($column, 'LIKE', '%' . $value . '%');
});
}
return $regions;
}
if (isset($conditions['search']) && !empty($conditions['search'])) {
$search = strtolower($conditions['search']);
$maintanceTechnician->orWhereRaw(
"LOWER(CONCAT(IFNULL(first_name,''),' ',IFNULL(last_name,''),' ',IFNULL(mobile_no,''))) like ?",
["%{$search}%"]
);
if (isset($conditions['post_code']) && !empty($conditions['post_code'])) {
$maintanceTechnician->orWhere('post_code', trim($conditions['post_code']));
}
}