2015-11-06 1 views
1

Это работает вручную, получая данные в виде массива затем repassing его:Как использовать пользовательские области запроса в запросе подсекции «Яркий»?

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

Я хочу быть способный создать «реальный» подзаголовок без необходимости иметь дубликаты копий областей запросов и запросов отношений только для каждой области. $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() не имеет значения.
  • Мне нужно выбирать между поддельными или не сухими областями пользовательских запросов.
  • Похоже, что основная проблема заключается в том, что механизм подзаголовка заставляет меня использовать ранее существовавший объект $query, который не может быть инициализирован из существующего отношения.
  • Воспроизведение мягких удалений (whereNull('deleted_at')) является тривиальным примером, но мне, возможно, придется воссоздать область запросов, которая уже может быть относительно сложной.

ответ

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() на отношение

+0

'whereHas' строго со стола. Каждый 'whereHas' вычисляет временный столбец для каждой таблицы. Это означает, что индексы не могут быть использованы, и будет проведено полное сканирование таблицы. У вас есть три 'whereHas' вложенные, что означает, что для каждой строки в пользовательской таблице MySQL должен выполнить вычисление столбца tmp« имеет groupMembership ». Чтобы определить, что каждое полное сканирование таблицы groupMember будет выполнять полное сканирование таблицы группы. Это по существу 3 слоя экспоненциально растущего полного сканирования таблицы. https://github.com/laravel/framework/issues/3543 – InstanceOfMichael