Reputation: 920
I am trying to avoid DRY in my query builder, specifically on adding additional method in the chain.
Example, this is initially the query builder that I have:
$products = $app->myShop->realProducts()
->where($query)
->skip($skip)->take($take)
->orderBy($sortKey, $sortOrder)
->get();
Then if user used some filter, I needed to append a method (specifically a whereHas()
) to the query builder
$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();
I find it "ugly" that to achieve this result, I have to keep repeating those builder query:
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();
}
Is there a more clever or elegant way to dynamically and conditionally append the whereHas()
method to the chain?
Hope somebody can help. Thank you!
Upvotes: 3
Views: 6439
Reputation: 1064
This could be done using Query Builder Conditional Clauses
$products = $app->myShop->realProducts()
->where($query)
->when($user_filtered_this_page, function($query) use($find){
$query->whereHas('colour', function ($q) use ($find) {
$q->where('colour_slug', $find);
})
})
->skip($skip)->take($take)
->orderBy($sortKey, $sortOrder)
->get();
Upvotes: 3
Reputation: 16283
The query doesn't get executed until you call ->get()
so you can quite simply build your query, conditionally add your ->whereHas()
and then execute it:
$query= $app->myShop->realProducts()
->where($query)
->skip($skip)->take($take)
->orderBy($sortKey, $sortOrder);
if (...) {
$query->whereHas(...);
}
$products = $query->get();
Upvotes: 13
Reputation: 3547
You can write like this:
$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();
Hope it help you ;)
Upvotes: 2