2017-02-18 35 views
0

Я пытаюсь избежать DRY в моем построителе запросов, в частности, о добавлении дополнительного метода в цепочку.eloquent - динамический и условный whereHas() в построителе запросов

Пример, это изначально строитель запрос, который у меня есть:

$products = $app->myShop->realProducts() 
     ->where($query) 
     ->skip($skip)->take($take) 
     ->orderBy($sortKey, $sortOrder) 
     ->get(); 

Затем, если пользователь использовал некоторые фильтры, мне нужно добавить метод (в частности, whereHas()) к построитель запросов

$products = $app->myShop->realProducts() 
     ->where($query) 
     ->whereHas('colour', function ($q) use ($find) { 
      $q->where('colour_slug', $find); 
     }) 
     ->skip($skip)->take($take) 
     ->orderBy($sortKey, $sortOrder) 
     ->get(); 

Я считаю, что «некрасиво», что для достижения этого результата, я должен повторять тот строитель запрос:

if ($user_filtered_this_page == TRUE) { 

    $products = $app->myShop->realProducts()->where($query) 
     ->whereHas('colour', function ($q) use ($find) { 
      $q->where('colour_slug', $find); 
     }) 
     ->skip($skip)->take($take) 
     ->orderBy($sortKey, $sortOrder) 
     ->get(); 

} else { 

    $products = $app->myShop->realProducts()->where($query) 
     ->skip($skip)->take($take) 
     ->orderBy($sortKey, $sortOrder) 
     ->get(); 
} 

Есть ли более умный или элегантный способ динамически и условно добавить метод whereHas() в цепочку?

Надеюсь, кто-то может помочь. Спасибо!

ответ

2

Запрос не начал выполняться, пока вы не вызовете ->get(), так что вы можете довольно просто построить свой запрос, условно добавить свой ->whereHas(), а затем выполнить его:

$query= $app->myShop->realProducts() 
    ->where($query) 
    ->skip($skip)->take($take) 
    ->orderBy($sortKey, $sortOrder); 

if (...) { 
    $query->whereHas(...); 
} 

$products = $query->get(); 
0

Вы можете написать так:

$products = $app->myShop->realProducts()->where($query) 
      ->whereHas('colour', function ($q) use ($find) { 
       if ($user_filtered_this_page) { 
       $q->where('colour_slug', $find); 
      } 
      }) 
      ->skip($skip)->take($take) 
      ->orderBy($sortKey, $sortOrder) 
      ->get(); 

Надеется, что это поможет вам;)

+0

я думаю, что это не даст желаемого результата, так как он будет пропускать 'realProducts()' 'без colour' отношения. –