2014-01-24 5 views
11

Кто-нибудь знает, может ли этот new feature выполнить несколько отношений?Laravel whereHas on multiple relationship

Например, у меня есть запрос, где я хочу фильтровать не только название клуба (related question), но и название территории.

В этом примере я хотел бы результаты запроса, где название клуба (клуб отношения) является Арсенал и регион Австралия (территория отношения)

$ret->with('territory')->with('homeClub')->with('awayClub'); 
    $ret->whereHas('territory',function($query){ 
      $query->where('region','Australia'); 
     })->whereHas('homeClub', function ($query) { 
      $query->where('name', 'Arsenal'); 
     })->orWhereHas('awayClub', function ($query) { 
      $query->where('name', 'Arsenal'); 
     }); 

При выполнении этого запроса - результат ISN» t сдерживая территорию whereHas только клубы один.

Могут ли быть привязаны, чтобы отфильтровать результаты по предыдущим отношениям где? Любые предложения, если нет?

благодаря

джон

ответ

16

Да, это возможно.

сгенерированного SQL, вероятно, будет:

SELECT * FROM ... WHERE (territory constraint) AND (homeClub constratint) OR (awayClub constraint) 

Это означает, что если awayClub constraint выполняется, то линия будет восстановлена. Я думаю, что вы хотите добавить скобки к сгенерированной SQL:

SELECT * FROM ... WHERE (territory constraint) AND ((homeClub constratint) OR (awayClub constraint)) 

, чтобы сделать это, вам нужно гнездо оба запроса внутри где:

$ret->with('territory')->with('homeClub')->with('awayClub'); 
    $ret->whereHas('territory',function($query){ 
     $query->where('region','Australia'); 
    }) 
    ->where(function($subQuery) 
    { 
     $subQuery->whereHas('homeClub', function ($query) { 
      $query->where('name', 'Arsenal'); 
     }) 
     ->orWhereHas('awayClub', function ($query) { 
      $query->where('name', 'Arsenal'); 
     }); 
    }); 
+0

Спасибо за ответ .. Этот синтаксис не похоже на работу. Не похоже, что 'whereHas' может использоваться в подзапросе. Я получаю сообщение об ошибке: 'SQLSTATE [42S22]: столбец не найден: 1054 Неизвестный столбец 'has' in 'where clause' (SQL: select * from' broadcasts' где (выберите count (*) из 'uploads', где' broadcasts' .upload_id' = 'uploads'.'id' и' type' = international-аудитория)> = 1 и (выберите count (*) из 'территорий', где' broadcasts'.'territory_id' = 'areas'.'id 'и' region' = Australia)> = 1 и ('has' = homeClub))' – HowApped

+0

Похоже, что orWhereHas ведет себя странно, когда вы применяете другие ограничения. См. Мой [другой вопрос SO] (http://stackoverflow.com/questions/21382870/orwherehas-parameter-grouping-on-eloquent-query-how-do-i-do-this-in-laravel) сгенерированным SQL , cheers – HowApped

+0

Работал для меня! Я делал что-то подобное с домашней командой и командой гостей, связанной с игровым столом. Debugbar сказал мне, что это результат: выберите * из 'games' где' season' = '2' и 'series' = '1' и ((выберите count (*) из' teams' где 'teams'.' id' = 'games'.'home_team_id' и' user_id' = '1')> = 1 или (выберите count (*) из 'commands' где' teams'. 'id' = 'games'.'visitor_team_id' и' user_id' = '1')> = 1) order by 'series' asc,' home_team_id' asc, 'game_number' asc ... Думаю, в этот момент мне лучше реорганизовать в но это хорошее упражнение. – tjans

7

Благодаря показывается в правильном направлении edi9999 - Я не был должным образом учитывая parameter grouping

use главный красноречивый объект в анонимной функции, я поместил whereHas и ограничение orWhereHas на Homeclub и awayClub и что сделал трюк.

$ret->with('territory')->with('homeClub')->with('awayClub')->with('programme'); 

    $ret 
     ->whereHas('territory',function($query) use ($parameterValues){ 
      $query->where('region', $parameterValues['region_names']); 
     }) 
     ->whereHas('season', function ($query) use ($parameterValues){ 
      $query->where('name', $parameterValues['season_names']); 
     }) 
     ->where(function($subquery) use ($ret){ 
      $ret->whereHas('homeClub', function ($query){ 
       $query->where('name','Arsenal'); 
      }); 
      $ret->orWhereHas('awayClub', function ($query){ 
       $query->where('name','Arsenal'); 
      }); 
     }); 
0

Я не думаю, что вам нужно «с» как есть «wherehas»

Model::whereHas('territory',function($query){ 
     $query->where('region','Australia'); 
    })->whereHas('homeClub', function ($query) { 
     $query->where('name', 'Arsenal'); 
    })->orWhereHas('awayClub', function ($query) { 
     $query->where('name', 'Arsenal'); 
    });