0

I have this relationship in tables.

consumers;id, name, site_id, tier_id

tiers:id, name, site_id

categories: id, name, site_id

consumer_categories: consumer_id, category_id

consumer_tiers: category_id, tier_id

And this is how I have set it up in models.

Consumer.php

public function tier(){
        return $this->belongsTo(Tier::class, 'tier_id');
    }
public function categories(){
        return $this->belongsToMany(Category::class, 'consumer_categories', 'consumer_id', 'category_id');
    }

Tier.php

public function consumers(){
        return $this->hasMany(Consumer::class, 'tier_id');
    }
public function categories()
    {
        return $this->belongsToMany(Category::class, 'category_tier', 'tier_id', 'category_id');
    }

And Category.php

public function consumers(){
        return $this->belongsToMany(Consumer::class, 'consumer_categories', 'category_id', 'consumer_id');
    }

Now when I run this query with site_id = 2

$site = Site::find(2);
$consumerQuery = $site->consumers()
            ->whereHas('categories.tiers')
            ->where(function($query) {
                $query->whereNull('tier_status_until')
                    ->orWhere('tier_status_until', '<', date('Y-m-d 00:00:00'))
                ;
            })
        ;

It works as expected but when I go to database and manually change one of the tiers's site_id to something else the consumer still shows up as if this query isn't validating site_id = 2 on whereHas

If I write something like this

$consumerQuery = $site->consumers()
            ->join('tiers AS t', 't.id', 'consumers.tier_id')
            ->where('t.site_id', '=', $site->id)
            ->where(function($query) {
                $query->whereNull('tier_status_until')
                    ->orWhere('tier_status_until', '<', date('Y-m-d 00:00:00'))
                ;
            })
        ;

It works perfectly and doesn't return the consumer who have the tier not associated with site_id = 2

Can someone help me fix the whereHas ?

Ali Rasheed
  • 2,765
  • 2
  • 18
  • 31
  • $consumerQuery = $site->consumers() ->whereHas('categories.tiers') ->where(function($query) { $query->whereNull('tier_status_until') ->orWhere('tier_status_until', '<', date('Y-m-d 00:00:00')) ; }) ; where is site id = 2 in this – hemanth rs Mar 04 '21 at 05:39
  • `$site` comes from `$site = Site::find(2)` – Ali Rasheed Mar 04 '21 at 06:06

0 Answers0