如何使用Scope在Eloquent ORM中选择除(A和B)之外的所有行?

时间:2015-01-10 20:53:28

标签: mysql laravel laravel-4 eloquent

我试图找出如何在Eloquent ORM模式中获得除少数(A和B)之外的所有行。

用户模型

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

模型通知

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

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

除了(友谊和已发送)范围以外,我如何获取用户的所有通知。

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

1 个答案:

答案 0 :(得分:3)

可以将范围与急切加载结合使用。像那样:

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

但是我们现在需要以某种方式反转范围。我可以想出两种解决方法。

1。添加否定范围

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。可选参数

或者您可以在当前范围中引入可选参数。像这样:

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');
}

这样你只需传入false:

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

修改

您甚至可以通过为booleanANDOR添加第二个参数来获得更多控制权:

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

如果你想要任何一个范围是真的:

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

第二次编辑

这个终于工作了(来自聊天)

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