2017-02-25 67 views
0

我具有以下模式:CakePHP3濾波基於自定義規則

用戶的hasMany RegistrationState RegistrationState 屬於關聯用戶

其經典1->中號關係,其中user_id說明是RegistrationState表。

RegistrationState具有以下屬性

id, user_id, state, created_at ... (others are not relevant) 

用戶可以有更多的註冊狀態,例如:

Registration state -> 1, created -> 01-02-2017 
Registration state -> 2, created -> 01-03-2017 
Registration state -> 3, created -> 01-04-2017 
Registration state -> 4, created -> 01-05-2017 
Registration state -> 2, created -> 01-06-2017 
Registration state -> 3, created -> 01-07-2017 

我需要在此基礎上「國有資產」,其中有效狀態是最後一個過濾器創建。

此示例的有效狀態是3,因爲它的最新狀態。現在

,我有CONTROLER和指數方法,在那裏我有

// push custom query for filtering to finder method 
    $this->paginate['finder'] = [ 
     'clients' => ['q' => $this->request->query] 
    ]; 

    try { 
     $clients = $this->paginate($this->Users); 
    } catch (\Exception $e) { 
     // redirect on main 
     return $this->redirect($this->here); 
    } 

取景方法看起來像這樣

public function findClients($query, array $options) 
{ 
    $opts = $query->getOptions()['q']; 

    if (!empty($opts['email'])) { 
     $query->andWhere(['email LIKE' => '%' . trim($opts['email']) . '%']); 
    } 

    if (!empty($opts['identity_num'])) { 
     $cn = $opts['identity_num']; 
     $query->matching('Identities', function ($query) use ($cn) { 
      $query->andWhere(['Identities.number' => $cn]); 
     }); 
    } 

    // registration state 
    if (!empty($opts['reg_state'])) { 
     // WHAT SHOULD BE HERE??? 
    } 

    return $query; 
} 

也有另一種1->中號的用戶關係 - >身份,但(匹配方法),但工作正常,因爲數字總是唯一的。

我無法解決註冊狀態的問題,我該如何在CakePHP3中實現這種搜索? (我不想打破分頁,所以我想在取景器的方法來解決這個問題)

+1

你想傳遞查詢狀態並根據最新的關聯狀態(與任何關聯狀態相反)是否與提供的值匹配來過濾用戶?這聽起來像一個[標籤:最大的每組]最大的問題,類似於[這個](http://stackoverflow.com/questions/30241975/how-to-limit-contained-associations-per-記錄組)**,但有一個額外的條件。現在沒時間給我一個詳細的答案,對不起。 – ndm

+0

@ndm感謝您的回覆。你正確和[這](http://stackoverflow.com/questions/30241975/how-to-limit-contained-associations-per-record-group)是非常有用的,但我不能實現,因爲我會打破現有的代碼:/我用子查詢解決了它 – xrep

回答

0

一個可能的(骯髒?)解決方案,這是子查詢(INNER JOIN上RegistrationState)

// registration state 
    if (!empty($opts['reg_state'])) { 

     $conn = ConnectionManager::get('default'); 


     $subquery = $conn->execute(
       'SELECT uir.user_id ' . 
       'FROM registration_state uir ' . 
       'INNER JOIN (' . 
        'SELECT user_id, max(created) as m_created ' . 
        'FROM registration_state ' . 
        'GROUP BY user_id ' . 
       ') muir ON uir.user_id = muir.user_id AND uir.created = muir.m_created AND uir.status = ' 
       . intval($opts['reg_state']) 
     ); 

     $usersInStateIds = []; 
     // transform result of subquery to usable array 
     foreach($subquery->fetchAll('assoc') as $r) { 
      $usersInStateIds[] = intval($r['user_id']); 
     } 
     $query->matching('RegistrationState', function ($query) use ($usersInStateIds) { 
      return $query->andWhere(['RegistrationState.user_id IN' => $usersInStateIds]); 
     }); 
    }