Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 Re: Хорошие практики (FAQ) » Хорошие практики - фильтры для товаров » 07.04.2018 01:42:57

Спасибо, видосик заценил. Очень в тему! Хотелось бы увидеть от вас побольше видосиков по теме рефакторинга)

#2 Хорошие практики (FAQ) » Хорошие практики - фильтры для товаров » 14.03.2018 03:31:30

makz
Ответов: 3

Доброго времени суток!
Знаком с ларавел примерно 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;
    }

Буду очень благодарен если поможете неопытному новичку своими советами)

Подвал раздела