Laravel универсальный select запрос в бд
не могу найти материалов, чтобы реализовать с помощью Laravel Eloquent какой-то плюс минус универсальный запрос выборки из базы данных. Чтобы он одинаково хорошо работал и с limit и без него, и с order by и без него, с условием и без и т.д. В обычном php это реализовывалось при помощи подачи в функцию массивов и переменных и в зависимости от них при помощи конкатенации получался составной запрос, а как делать что-то подобное в Laravel? Ведь, в ларе это не просто string строка, которую можно сунуть в query запрос и т.д., здесь же обращение к методам класса идет. Не понимаю, как это реализовать. Спасибо за внимание=)
Ответы (2 шт):
Можно использовать when()
function getAllRecords($limit=false, $offset=false, $order=false)
{
$records = Record::whereNotNull('title')
->when($limit, function ($query, $limit) {
return $query->limit($limit);
})
->when($offset, function ($query, $offset) {
return $query->offset($offset);
})
->when($order, function ($query, $order) {
return $query->orderBy($order);
})
->get();
return $records;
}
А можно и так:
function getAllRecords($limit=false, $offset=false, $order=false)
{
$records = Record::whereNotNull('title');
if ( !empty($limit) && !empty($offset) ) {
$records = $records->limit($limit)->offset($offset);
}
if ( !empty($order) ) {
$records = $records->orderBy($order);
}
$records = $records->get();
return $records;
}
Принцип тут тот же, только вместо строки собирается объект.
В дополнение к InDevX:
Думаю лучше подобные методы вешать на скопы модели
/**
* @param Illuminate\Database\Eloquent\Builder $builder
* @param int|null $limit
* @param int|null $offset
* @param string|null $order колонка по которой будет производится сортировка
*
* @return Illuminate\Database\Eloquent\Collection
*/
public function scopeGetAllRecords(
Builder $builder,
?int $limit = null,
?int $offset,
?string $order = null
): Collection {
return $builder->whereNotNull('title')
->when($limit, function(Builder $subBuilder, int $limit) {
return $subBuilder->limit($limit);
})->when($offset, function(Builder $subBuilder, int $offset) {
return $subBuilder->offset($offset);
})->when($order, function(Builder $subBuilder, int $order) {
return $subBuilder->reorder($order);
})->get();
}
Теперь когда вы вызываете какую либо модель вы можете сразу обратится к скопе
Model::getAllRecords($limit, $offset, $order);
Либо добавить какое то условие если оно вдруг понадобиться
Model::where('active', true)->getAllRecords($limit, $offset, $order);