简体   繁体   中英

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.

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!

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM