Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

abdulaziz's avatar

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();
    }
}
0 likes
0 replies

Please or to participate in this conversation.