2014-03-01 5 views
0

Предположит, что у вас есть отношения, как в следующем, и вы хотите, чтобы найти все счета, которые находятся под данным клиентом:Рекурсивных найти вложенные активные записи отношения в Yii

- Customer 1 
    - accounts 
     - Account 1 
    - customers 
     - Customer 2 
      - accounts 
       - Account 2 
       - Account 3 
     - Customer 3 
      - customers 
       - Customer 4 
        - accounts 
         - Account 4 
         - Account 5 

(для Клиента 1, это составляет 1, 2, 3, 4 и 5, для Клиента 3 - счета 4 и 5 и т. Д.)

Как вы это сделаете?

Это появилось несколько раз в моих проектах, и мне любопытно, как другие решили это.

Вот в gist of my solution (комментарии кода в ссылке):

<?php 
public function getNestedRelated($nested, $from, $nestedCriteria = array(), $fromCriteria = array(), $maxLevels = false, $includeFirst = true, $_currentLevel = 0, &$_recursedSoFar = array()) 
{ 
    // Always return an array (for array_merge) 
    $related = array(); 

    // Prevent infinite recursion 
    if (in_array($this->primaryKey, $_recursedSoFar)) { 
     return $related; 
    } 
    $_recursedSoFar[] = $this->primaryKey; 

    // Nested records at this level 
    if ($_currentLevel > 0 || $includeFirst) { 
     // Whether to refresh nested records at this level. If criteria are 
     // provided, the db is queried anyway. 
     $refreshNested = false; 
     $related  = $this->getRelated($nested, $refreshNested, $nestedCriteria); 
    } 

    // Handle singular ("HAS_ONE", "BELONGS_TO") relations 
    if (!is_array($related)) { 
     $related = array($related); 
    } 

    // Don't recurse past the max # of levels 
    if ($maxLevels !== false && $_currentLevel > $maxLevels) { 
     return $related; 
    } 

    // Whether to refresh children of this record. If criteria are provided, 
    // the db is queried anyway. 
    $refreshFrom = false; 

    // Go down one more level 
    $_currentLevel++; 
    foreach ($this->getRelated($from, $refreshFrom, $fromCriteria) as $child) { 
     // Recursive step 
     $nestedRelated = $child->getNestedRelated($nested, $from, $nestedCriteria, $fromCriteria, $maxLevels, $includeFirst, $_currentLevel, $_recursedSoFar); 
     $related  = array_merge($related, $nestedRelated); 
    } 
    return $related; 
} 

ответ

0

Вы думали об использовании предзаказ, чтобы получить все детали в 1 идут? Если это возможно, сохраните учетную запись и клиентов в одной таблице, тогда 1 запрос с предварительным заказом фактически получит все, что вам нужно.

Если вы храните клиентов и учетные записи в двух разных таблицах, я считаю, что вы все равно можете использовать предварительный заказ, чтобы свести к минимуму количество запросов.

Я использую в Yii это удлинение, так что держите вещи в предварительном порядке, довольно хорошо http://www.yiiframework.com/extension/nestedsetbehavior/