@freelancer007

Как правильно построить запрос (Laravel)?

Всем доброго дня! И хорошего настроения!
Возник вопрос по правильному построению запроса
Есть таблица с регионами:
Table name `regions`
`region_id` (int);
`region_name`(varchar);
`region_code`(int);

Таблица с категориями:
Table name `categories`
`cat_id` (int);
`cat_name`(varchar);

Таблица с товарами:
Table name `goods`
`good_id` (int);
`good_name`(varchar);
`good_region`(int);
`good_cat`(int);

Хочу добиться чтобы ссылка имела такой вид site.ru/moskow/audio/2452145

в route.php пишу маршрут такого вида:
Route::get('/{region}/{category}/{id}','GoodsController@show');

Содержимое GoodsController метод show
public function show($region, $category, $id){
//тут у меня тупик
}

Теперь вопрос:
1. Нужно проверить в базе есть ли регион с именем Москва, и вытащить его ID
2. Нужно проверить в базе есть ли такая категория и вытащить ее ID
3. Проверить принадлежит ли товар к этой категории и к этому региону
4. Если все верно, то показать товар
5. Если не принадлежит к региону или не принадлежит к категории то 404

Как мне правильно построить такой запрос и\или несколько запросов, чтобы не городить огород ))
Спасибо!
  • Вопрос задан
  • 449 просмотров
Решения вопроса 1
miraage
@miraage
Старый прогер
Подразумевается, что связи настроены корректно.
И не забудьте индексы по полям cat_name, region_name.

Ссылка на документацию.

$result = Goods::query()
    ->whereHas('category', function ($query) use ($category) {
        /** @var \Illuminate\Database\Query\Builder $query */
        $query->where('cat_name', $category);
    })
    ->whereHas('region', function ($query) use ($region) {
        /** @var \Illuminate\Database\Query\Builder $query */
        $query->where('region_name', $region);  
    })
    ->where('id', $id)
    ->with('category', 'region')
    ->first(); // можно ->firstOrFail() = само выкинет ошибку

if ($result === null) {
    // 404
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
DJZT
@DJZT
Laravel - code for you
Для начала сделайте связи в моделях. Так будет легче.
public function show($region, $category, $id){
$Region = Region::where('region_code', '=', $region)->first();
$Category = Category::where('cat_name', '=', $category)->first();
$Region->products()->where('good_region', $Region->id)->where('good_cat', '=', $Category->id)->where('id', '=', $id)->first();
return view(...) 
}

Это самый примитивный вариант. Можно сделать всё одной строчкой. Но вы подучите eloquent и вы сами поймёте как это сделать
А проверки сами расставите.
Ответ написан
Tesla
@Tesla
Можно забиндить модели в роутах.
Route::model('region', \App\Models\Region::class);
Route::model('category', \App\Models\Category::class);
Route::model('good', \App\Models\Good::class);

Route::get('/{region}/{category}/{good}', 'GoodsController@show');

Модели инжектятся в роуты и автоматически проверяются на существование. В контроллере будут готовые экземпляры моделей.
public function show(Region $region, Category $category, Good $good){
//
}

Вам останется только проверить, принадлежит ли товар к этой категории и к этому региону.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы