Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Спасибо, видосик заценил. Очень в тему! Хотелось бы увидеть от вас побольше видосиков по теме рефакторинга)
Доброго времени суток!
Знаком с ларавел примерно 2 месяца, поэтому сразу прошу камнями не бросаться и обьяснить чайнику (мне) что к чему.
Последний месяц пишу API-приложение. Писал я себе не очем не задумываясь, а потом заметил, что у меня некоторые методы в контролере очень жырные.
И здесь я задумался о рефакторинге кода. Начинал искать разные примеры, литературу и так далее. Наткнулся на ваш замечательный форум и решил поспрашывать опытних людей поделиться умом-разумом.
Лучше всего понимаю на примерах, поэтому хочу попросить обьяснить мне на одном с моих методов.
Суть в следующем:
У меня есть метод который возвращает список товаров. Дальше, надо сделать возможным применять к ним фильтры.
Есть следующие фильтры: category, shop, price, sizes, colors и order_column, order_direction. И самое главное я могу попробовать получить товары только по одному фильтру или по нескольким или по всем сразу.
При изучении моей проблемы наткнулся на такие понятия как паттерн репозиторий и сервисы. Судя по тому, что я использую Eloquent, репозитории мне не подходят, а вот насчет сервисов я заинтересовался (на них хорошых примеров не нашел). Но как использовать эти сервисы? Что туда выносить? И как их правильно использовать?
Также, уже понял, что все запросы можно вынести в модель (аля fat model, skiny controller). Но, как избавиться от всех этих if'ов и максимально сделать код читабельным? Ведь некоторые параметры могут прийти, а некоторые нет.
Также хотелось спросить за вынесенеи валидации в Form Request, как это сделать к параметрам которые содержаться в URI:
(пример: example.com/api/products?category=2&shop=4&order_column=created_at&order_direction=desc), тобиш праметры находяться в ссылке.
Вот собственно код метода:
public function index()
{
$validator = $this->validateParams(request()->all());
if ($validator->fails()) {
return response()->json(['message' => 'wrong_filters'], 422);
}
$whereInFilters = request()->only('sizes', 'colors');
$products = Product::with('colors', 'sizes', 'currency', 'images');
if (request()->has('shop')) {
$products->where("shop_id", request('shop'));
}
if (request()->has('category')) {
$categoryModel = Category::find(request('category'));
$categories = $categoryModel->descendants()->pluck('id');
$categories[] = $categoryModel->getKey();
$products->whereIn('category_id', $categories);
}
foreach ($whereInFilters as $filter => $value) {
$products->whereHas($filter, function ($query) use ($filter, $value) {
$query->whereIn("{$filter}.id", json_decode($value));
});
}
if (request()->has('price')) {
$products->whereBetween('price', json_decode(request('price')));
}
if (request()->has('order_column')) {
$products->orderBy(request('order_column'), request('order_direction'));
}
$products = $products->paginate(request()->has('per_page') ? request('per_page') : null);
return response()->json($products, 200);
}
/**
* Validate path params
*
* @param $params
* @return \Illuminate\Validation\Validator
*/
public function validateParams($params)
{
$validator = Validator::make($params, [
'shop' => 'integer|exists:shops,id',
'category' => 'integer|exists:categories,id',
'sizes' => 'json|size:2',
'sizes.*' => 'integer',
'colors' => 'json',
'colors.*' => 'integer',
'price' => 'json',
'order_column' => 'required_with:order_direction|string',
'order_direction' => 'required_with:order_column|in:asc,desc',
]);
return $validator;
}
Буду очень благодарен если поможете неопытному новичку своими советами)