John Halsey
John Halsey

Reputation: 2008

Get all rows except any models already related

So I have 2 models in Laravel 5.3. Practice and Offer, they have a many to many relationship which is set up and working. I can attach offers to practices etc. I want to retrieve all offers that are not already related to the practice.

The logged in user also belongs to the practice with practice_id.

In my controller I am passing in $offer in the constructor which just relates to all offers. I've tried using the reject() method as below but I'm getting nothing back, and I can't figure it out.

If I use $this->offer I get everything.

$query = $this->offer->reject(function($offer){
    return $offer->whereHas('practices', function($q) {
        return $q->where('practice_id', Auth::user()->practice_id);
    });
});

Releations

User Model

public function practice()
{
    return $this->belongsTo(Practice::class);
}

Practice Model

public function users()
{
    return $this->hasMany(User::class, 'practice_id');
}

public function offers()
{
    return $this->belongsToMany(Offer::class, 'offer_practice')->withTimestamps();
}

Offer Model

public function practices()
{
    return $this->belongsToMany(Practice::class, 'offer_practice')->withTimestamps();
}

Please help.

Upvotes: 1

Views: 64

Answers (2)

John Halsey
John Halsey

Reputation: 2008

I've managed to work it out like this with the help of @SaumyaRastogi into one small query.

$offers = $this->offer->whereHas('practices', function($q) {
    $q->where('practice_id', '<>', auth()->user()->practice->id);
})->orHas('practices', '<', 1)->get();

Upvotes: 1

Saumya Rastogi
Saumya Rastogi

Reputation: 13699

You can take the use of whereHas like this:

This query gives you those offers which aren't related to those practices which have relationship with the authenticated user.

$offers = Offer::whereHas('practices', function($q) {
    $q->where('id', '<>', auth()->user()->practice->id);
});

UPDATE:

Whereas, the below query gives you those offers which aren't related to those practices which have relationship with any of the users in the DB.

$practice_id_arr = Practice::has('users')->pluck('id')->all();

$offers = Offer::whereHas('practices', function($q) use($practice_id_arr) {
    $q->whereNotIn('id', $practice_id_arr);
});

Below query gives you those offers that are not associated with any of the practices:

$offers = Offer::doesntHave('practices')->get();

Below query gives you those offers that are associated with all practices:

$offers = Offer::has('practices')->get();

Hope this helps!

Upvotes: 1

Related Questions