2014-04-21 1 views
0

У меня есть таблица users, таблица role_members и таблица ролей.Как сортировать или выполнять поиск в CakePHP на основе глубоких ассоциаций моделей?

Таблица role_members имеет user_id и role_id, поскольку пользователи могут иметь много ролей.

У меня есть DataTable, в котором есть идентификатор пользователя, адрес электронной почты, имя и роли. Я могу легко сортировать и фильтровать на основе полей в таблице users. Как работает DataTable, есть одно окно поиска, которое ищет все поля. Итак, мой поисковый запрос должен быть «OR», где имя пользователя, например search_term ИЛИ email, как search_term ИЛИ имя роли, например search_term

Проблема возникает, когда я пытаюсь сортировать или фильтровать на основе имен ролей. Если я хочу сортировать по RoleMember.Role.name или искать по RoleMember.Role.name, как это сделать?

Мои найти варианты заключаются в следующем:

$sOrder = array('User.full_name' => 'asc'); 

    if (isset($params['iSortCol_0'])) { 

     $sOrder = array(); 
     for ($i=0 ; $i<intval($params['iSortingCols']) ; $i++) 
     { 
      if ($params[ 'bSortable_'.intval($params['iSortCol_'.$i]) ] == "true") 
      { 
       $sOrder[$columns[ intval($params['iSortCol_'.$i]) ]] = $params['sSortDir_'.$i] ; 
      } 
     } 

    } 

    $find_options = array(
     'order' => $sOrder, 
     'contain' => array(

      'RoleMember' => array('Role', 'Instance'), 
      'AllowedLocation' 

     ), 
     'limit' => $limit, 
     'offset' => $offset 
    ); 


    if(isset($params['sSearch'])){ 
     $search_term = '%'. $params['sSearch'] .'%'; 
     $find_options['conditions'] = array(

      'Or' => array(
       'User.full_name LIKE ' => $search_term, 
       'User.email LIKE ' => $search_term, 
       'User.username LIKE ' => $search_term 
       //'RoleMember.Role.name LIKE ' => $search_term, 

      ) 

     ); 
    } 
+1

как насчет использования 'joins'? –

+0

Пробовал. По какой-то причине они, похоже, не применяются. Сначала я подумал, что это потому, что я использую сдержанный, но я не уверен. Думаю, я должен вырваться из отладчика и посмотреть, смогу ли я понять, что происходит. –

ответ

1

присоединяется, безусловно, работать, но это будет очень неэффективно, если не кэшировать запрос ... Теперь попробуйте this-

$options['joins'] = array(
         array(
          'table' => 'role_members', 
          'alias' => 'RoleMember', 
          'type' => 'INNER', 
          'conditions' => array(
           'RoleMember.user_id = User.id' 
          ) 
         ), 
         array(
          'table' => 'roles', 
          'alias' => 'Role', 
          'type' => 'INNER', 
          'conditions' => array(
           'RoleMember.role_id = Role.id' 
          ) 
         ) 

); // here we join all the tables, so all fields are available to place conditions... 

$options['conditions'] = array(
          'OR' => array(
           'User.full_name LIKE ' => $search_term, 
           'User.email LIKE ' => $search_term, 
           'User.username LIKE ' => $search_term 
           'Role.name LIKE ' => $search_term, 
          ) 
); 

$users = $this->User->find('all', $options); 
+0

Просто подсказка для любого, кто приходит, что пытается сделать что-то подобное, мне также нужно было сделать GROUP BY User.id –

+0

Добавить '$ options ['group'] = array (User.id);' –