1

I the following scenario: I have a listings and locations tables. A category has many locations and a listing can belong to many locations (many to many relationship). Here is how my models look like:

Table structure for listings

  • id,
  • name,
  • time_stamps

Listing Model (App\Models\Listing)

public function locations() {
        return $this->belongsToMany('App\Models\Location', 'listing_locations', 
          'listing_id', 'location_id');
    }

Table structure for locations

  • id,
  • name,
  • timestamps

Location Model (App\Models\Location)

public function listings() {
        return $this->belongsToMany('App\Models\Listing', 'listing_locations', 
          'location_id', 'listing_id');
    }

Pivot table (listing_locations) structure:

  • id,
  • listing_id,
  • location_id

Everything works fine - I can get listings with their locations and vice versa. The problems sets in when I want to filter the listings - I want to only get listings which belong to particular locations (the locations are in an array coming from a front end). One problem I have is the location names in the database are Google map location names e.g 207-192 Spadina Ave, Toronto, ON M5T 2C2, Canada but user is only filtering with Canada so I have to use like.

Here is what I have so far:

$listings = Listing::where('id', '>', 0);

    $countries = $request->query('countries');
    
                foreach ($countries as $country) {
                    $conditions[] = ['name', 'like', '%' . $country . '%'];
                }
    
                
                $listings->whereHas('location', function($q) use ($conditions) {
                    $q->where($conditions);
                });

However, this only works when the countries array (filter) has only one value. I have also tried using orWhere but this does not apply the filter.

Have also tried this

$listings->whereHas('location', function($q) use ($countries) {
                for ($i = 0; $i < sizeof($countries); $i++){
                    $q->orwhere('name', 'like',  '%' . $countries[$i] .'%');
                } 
            });

but does not work.

Any idea how this should work?

8
  • what you get in dd($countries) ? Commented Jul 9, 2021 at 8:20
  • @JohnLobo dd($countries) has all selected countries in an array array:2 [▼ 0 => "Spain" 1 => "Taiwan" ] Commented Jul 9, 2021 at 8:28
  • if its exact word of country then you can use wherein Commented Jul 9, 2021 at 8:33
  • Not exact work ... thus the need of applying LIKE % $country % Commented Jul 9, 2021 at 8:35
  • whats the issue of second query Commented Jul 9, 2021 at 8:35

1 Answer 1

2

Group multiple where conditions using where callback

 $listings->when(count($countries),function ($query)use ($countries) {
        
         $query->whereHas('location', function($q) use ($countries) {
            $q->where( function($q) use ($countries) {
                foreach ($countries as $country) {
                  $q->orWhere('name', 'like', '%' . $country . '%');
               }
            });
        });
        
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.