Имеется 2 таблицы в БД:
1) cars - хранит записи авто:
id | manufacturer | model | description ...
2) cars_prices_history - хранит историю цен на авто (цена может быть акционной, а может быть не акционной)
id | car_id | price | is_sale | sale_expires | date |
-------------------------------------------------------------------------
1 | 1 | 23000 | 1 | 27-08-2021 | 27-04-2020 |
-------------------------------------------------------------------------
2 | 1 | 34000 | 0 | NULL | 27-04-2020 |
-------------------------------------------------------------------------
3 | 2 | 27500 | 0 | NULL | 28-04-2020 |
Есть 2 модели со связями (Laravel Relationships):
Car:
class Car extends Model
{
protected $table = 'cars';
public function priceHistory() {
return $this->hasMany(Car_price_history::class);
}
}
Car_price_history:
class Car_price_history extends Model
{
protected $table = 'cars_prices_history';
public function car() {
return $this->belongsTo(Car::class);
}
}
Контроллер, который обрабатывает запрос роута `api/v1/cars`:
public function index(Request $request, Car $cars)
{
$cars = Car::with('priceHistory'); // получаю билдер
if ($request->has('minPrice') && !empty($request->minPrice))
{
// здесь должен быть фильтр, который должен через модель Car_price_history
// сходить к БД, найти все цены, у которых car_id будет равно id-шнику авто (непонятно, откуда
// брать id авто, если в $cars сидит билдер, а коллекцию я получить не могу до запроса,
// а даже если получу, то мне придётся запускать foreach для каждого авто и перелопачивать всю коллекцию??
// или делать это при помощи методов коллекций, но всё равно выглядит странно), взять последнюю
// акционную цену, а если акционной нет, то взять последнюю не акционную. И только потом, получив цену,
// применить фильтр, который отсеит авто. И такая логика для каждого фильтра.
$cars->where('price', '>=', $request->minPrice); // не работающий фильтр
}
$cars = $cars->get(); // получаю коллекцию
return new CarCollection($cars);
}
Мне необходимо добавить фильтры, чтобы отфильтровать все авто по нескольким фильтрам:
1) минимальная цена - minPrice
2) максимальная цена - maxPrice
3) наличие скидки - sale
и другие. Чтобы контроллер обрабатывал роут вида `api/v1/cars?minPrice=1000&maxPrice=21000&sale=1` и применял соответствующие фильтры, а потом отдавал в CarCollection (Eloquent API Resourse) только те результаты, которые прошли через фильтры.
В общем, вообще не понятно, каким образом можно сделать фильтрацию такого рода? Каким образом можно получать последнюю цену и делать фильтр на неё? Или может проще добавить в миграцию авто столбцы
price
и
sale_price
? Но у меня помимо cars_prices_history есть ещё таблицы, которые отношениями связаны с моделью Car и добавление столбцов во-первых заставит дублировать данные, а во-вторых, нарушает правила нормализации таблиц, то есть идея странная тоже.
Как сделать фильтры? Может есть вариант попроще, что бы реализовать фильтр по цене? Посоветуйте статейки, видео по этой теме