How can I select all rows except (A and B) in Eloquent ORM using Scope?

I am trying to figure out how to get all but a few rows (A and B) in an ORICO ORACLE module.

User model

public function notifications()
{
    return $this->hasMany('notification','listener_id','id');
}

      

Model Notification

public function scopeFriendship($query)
{
    return $query->where('object_type', '=', 'Friendship Request');
}

public function scopeSent($query)
{
    return $query->where('verb', '=', 'sent');
}

      

Here's how I can get all user notifications except the area (Friendship and Sent).

Something like:- all rows except !(Friendship AND Sent)

      

+3


source to share


1 answer


You can use areas in combination with active loading. For example:

User::with(['notifications' => function($q){
    $q->friendship();
}])->get();

      

However, we need to invert the area somehow. I can think of two ways to solve this problem.

1. Add negative areas

public function scopeNotFriendship($query){
    return $query->where('object_type', '!=', 'Friendship Request');
}

public function scopeNotSent($query){
    return $query->where('verb', '!=', 'sent');
}

User::with(['notifications' => function($q){
    $q->notFriendship();
    $q->notSent();
}])->get();

      

2. Optional parameter

Or you can enter an optional parameter in the current scopes. Something like that:

public function scopeFriendship($query, $is = true)
{
    return $query->where('object_type', ($is ? '=' : '!='), 'Friendship Request');
}

public function scopeSent($query, $is = true)
{
    return $query->where('verb', ($is ? '=' : '!='), 'sent');
}

      

This way you only need to pass false:



User::with(['notifications' => function($q){
    $q->friendship(false);
    $q->sent(false);
}])->get();

      

Edit

You can even get more control by adding a second parameter for boolean

( AND

or OR

where:

public function scopeFriendship($query, $is = true, $boolean = 'and')
{
    return $query->where('object_type', ($is ? '=' : '!='), 'Friendship Request', $boolean);
}

      

And if you want the scope to be true:

$q->friendship(true, 'or');
$q->sent(true, 'or');

      

2nd Edit

This one finally worked (from chat)

Notification::where('listener_id', $user_id) 
    ->where(function($q){ 
        $q->friendship(false) 
        $q->sent(false, 'or') 
    }) 
    ->get();

      

+3


source







All Articles