Cant figure out joins
So I am making a Businesses web app with the filters feature. There are two filters that I have problem with: Order By and Attributes(Has following attributes) features. Which looks like this:
Order By
- Highest Rated (radio button)
- Most reviews (radio button)
Attributes
- Accepts Credit Cards (checkbox)
- Accepts Events (checkbox)
- Alcohol (checkbox)
- Delivery (checkbox)
- Smoking (checkbox)
So when Order By option is clicked this function is executed. Where $term is value of order_by get request parameter.
BusinessFilter.php
public function orderby($term)
{
if ($term == 'reviews_count') {
return $this->builder
->leftJoin('reviews', 'businesses.id', '=', 'reviews.business_id')
->groupBy('businesses.id')
->selectRaw('businesses.*, COUNT(reviews.id) as reviews_count')
->orderByDesc('reviews_count');
} else if ($term == 'rating') {
return $this->builder
->leftJoin('reviews', 'businesses.id', '=', 'reviews.business_id')
->groupBy('businesses.id')
->selectRaw('businesses.*, AVG(reviews.rating) AS average')
->orderByDesc('average');
} else {
return $this->builder;
}
}
It works ok and the result is correct.
Now when Attribute have some check boxes this function is executed where $term is an array with set of ids.
BusinessFilter.php
public function attributes($term)
{
$attributes= json_decode($term);
if (count($attributes) == 0) {
return $this->builder;
}
return $this->builder
->select('businesses.*')
->join('business_attribute_value', 'businesses.id', '=', 'business_attribute_value.business_id')
->join('values', 'business_attribute_value.attribute_value_id', '=', 'values.id')
->whereIn('values.id', $attributes)
->groupBy('businesses.id')
->havingRaw('COUNT(*) = ?', [count($attributes)]);
}
the result is correct here too.
Now the problem is when both filters have values it executes both queries together and It doesn't return the correct result. I assume it has something to do with joins. Am I doing something wrong? Please help. And if you need more info or code please let me know. Thank you, you are the best guys!
This is how I execute filters
public function getSearch(BusinessFilter $filters)
{
$businesses = Business::filter($filters)->paginate(30);
return $businesses;
}
This is QueryFilter class. Basically what it does is that it goes through each request parameter and executes its function that was mentioned above.
class QueryFilters{
protected $request;
protected $builder;
public function __construct( Request $request )
{
$this->request = $request;
}
public function apply(Builder $builder)
{
$this->builder = $builder;
foreach( $this->filters() as $name => $value ){
if( !method_exists($this, $name ) ){
continue;
}
if(strlen($value)){
$this->$name($value);
} else {
$this->$name();
}
}
return $this->builder;
}
public function filters()
{
return $this->request->all();
}
}
Please or to participate in this conversation.