如何在Eloquent子选择查询中使用自定义查询范围?

时间:2015-11-06 20:03:24

标签: laravel eloquent query-builder

这可以通过手动将数据作为数组获取然后将其复原来实现:

public function scopeWhereWhitelisted($query, $value=true, Tenant $tenant)
{
    return $query->where(function($query)use($value,$tenant)
    {
        $user_id_list = $tenant->getWhiteListedUsersGroup()
                                                ->users()
                                                ->select('users.id')
                                                ->lists('id')
                                                ->all()
        ;

        $query->{ $value ? 'whereIn' : 'whereNotIn' }('users.id',$user_id_list);
    });
}

但是我想要这个工作(注释//表示唯一的区别):

public function scopeWhereWhitelisted($query, $value=true, Tenant $tenant)
{
    return $query->where(function($query)use($value,$tenant)
    {
        $user_id_list = $tenant->getWhiteListedUsersGroup()
                                                ->users()
                                                ->select('users.id')
                                                //->lists('id')
                                                //->all()
        ;

        $user_id_list = $tenant->getWhiteListedUsersGroup()->users()->select('users.id');//->lists('id')->all();
        $query->{ $value ? 'whereIn' : 'whereNotIn' }('users.id',$user_id_list);
    });
}

我希望能够创造一个真实的" subselect,无需为每个范围都拥有自定义查询范围和关系查询的重复副本。 $tenant->getWhiteListedUsersGroup()->users()是多对多关系

以下是获取真实子选择所需做的一个示例:

public function scopeWhereWhitelisted($query, $value=true, Tenant $tenant)
{
    return $query->where(function($query)use($value,$tenant)
    {
        $query->{ $value ? 'whereIn' : 'whereNotIn' }('users.id',function($query)
        {
             $query->from('groups_memberships')
                  //     recreating an existing relationship function
                  ->join('groups','groups.id','group_memberships.group_id')
                  ->select('users.id')
                  //     recreating an already existing query scope
                  ->whereNull('deleted_at')
             ;
        });
    });
}
  • 这个问题很可能适用于Laravel 4.0+和5.0 +
  • How to do this in Laravel, subquery where in
  • 未回答此问题
  • 当我需要第二个非平凡的子选择时,重构代码以便从预期的子查询开始查询将不起作用。
  • ->getQuery()的加入/排除没有任何区别。
  • 我必须在假的subselect或非DRY自定义查询范围之间进行选择。
  • 似乎主要问题是子选择引擎迫使我使用预先存在的$query对象,该对象无法从现有关系初始化。
  • 重新删除软删除(whereNull('deleted_at'))是一个简单的例子,但我可能不得不重新创建一个可能相对复杂的查询镜。

1 个答案:

答案 0 :(得分:0)

这是你的事吗?

$value; //true or false

$tenant->whereHas('user', function($query) use ($value){
    $query->whereHas('groupMembership', function($query) use ($value){
        $query->whereHas('group', function($query) use ($value){
            if($value){ $query->onlyTrashed(); )
        });
    })
})

这假设组关系包含关系

上的withTrashed()调用