← Заметки и статьи о Laravel PHP

8 июня 2016 перевод

Пример использования макроса для QueryBuilder

Предположим у нас есть следующая выборка:

$results = DB::table('orders')->where('branch_id', Auth::user()->branch_id)->get();

И нам необходимо добавить дополнительное условие в зависимости от наличия параметра в запросе. Мы можем сделать это так:

$results = DB::table('orders')->where('branch_id', Auth::user()->branch_id);

if ($request->customer_id) {
	$results->where('customer_id', $request->customer_id);
}

$results = $results->get();

Задача решена, но выглядит не очень красиво. Начиная с Laravel 5.2.27 можно отрефакторить так:

$results = DB::table('orders')
    ->where('branch_id', Auth::user()->branch_id)
    ->when($request->customer_id, function($query) use ($request) {
        return $query->where('customer_id', $request->customer_id);
    })
    ->get();

Используя when() мы можем не разрывать цепочку методов. Выглядит уже лучше, но всё ещё не очень красиво — число строк не изменилось и появился уродливый callback.

Воспользуемся макросом QueryBuilder. Для начала создадим его:

Builder::macro('if', function ($condition, $column, $operator, $value) {
    if ($condition) {
        return $this->where($column, $operator, $value);
    }

    return $this;
});

И применим для нашего случая:

$results = DB::table('orders')
    ->where('branch_id', Auth::user()->branch_id)
    ->if($request->customer_id, 'customer_id', '=', $request->customer_id)
    ->get();

Стало красивше и подходит для простых случаев, когда у нас мало условий. Если же условий много, то лучше вынести их обработку в отдельный класс (урок на Laracasts).

Источник: http://themsaid.com/laravel-query-conditions-20160425/

Плюсануть
Поделиться
Отправить