Я использую области локальных запросов в модели, чтобы добавить несколько подзапросов для агрегирования некоторых значений. Затем они отображаются в моих шаблонах Blade и используются как условные выражения для отображения определенных частей пользовательского интерфейса.
Это выглядит примерно так (усечено и переименовано для краткости)
public function scopeWithFilterData(Builder $query)
{
$query->addSelect(['sub_query_aggregate'] => ...
}
У меня также есть область использования этих агрегированных значений для фильтрации моделей. Я проверяю, был ли добавлен подзапрос через область видимости, и в противном случае добавляю его, чтобы сделать агрегаты подзапроса доступными.
public function scopeFilterData(Builder $query)
{
$query->when($this->hasFilterDataScope($query), function ($query) {
$query-> scopeWithFilterData();
})
->havingRaw('sub_query_aggregate IS NULL');
}
Однако я не нашел хорошего способа проверить, была ли применена локальная область уже, поэтому метод hasFilterDataScope проверяет, присутствует ли агрегированное имя в свойстве столбцов объектов Query Builder.
private function hasNeedsAttentionScope(Builder $query)
{
$columns = $query->getQuery()->columns;
return is_null($columns)
|| count(preg_grep('/sub_query_aggregate/', $columns)) === 0;
}
Он выполняет свою работу, но не очень Laravel -esque. Есть ли способ сделать это лучше и / или чище?