Доступ к более чем одной модели глубоких отношений в Lithium - PullRequest
4 голосов
/ 23 марта 2012

Можно ли получить доступ к более чем одной модели в отношениях в Литии?

Например, у меня есть модель User:

class Users extends \lithium\data\Model {
    public $validates = array();
    public $belongsTo = array("City");
}

, и у меня есть модель City:

class Cities extends \lithium\data\Model {
    public $validates = array();
    public $belongsTo = array("State");
}

и модель состояния и т. Д.

Если я запрашиваю пользователя, с чем-то похожим на Users::first(), возможно ли включить все отношенияс результатами?Я знаю, что могу сделать Users::first(array('with' => 'City')), но я бы хотел, чтобы каждый Город также возвращал свою модель государства, чтобы я мог получить к ней доступ следующим образом:

$user->city->state->field

Сейчас я могу только заставить его пойтиодин глубокий ($user->city), и мне придется снова запрашивать, что кажется неэффективным.

Ответы [ 3 ]

9 голосов
/ 20 февраля 2013

Используя недавний мастер, вы можете использовать следующие вложенные обозначения:

Users::all( array( 
    'with' => array(
        'Cities.States'
    ) 
)); 

Он сделает для вас СОЕДИНЕНИЯ.

3 голосов
/ 23 марта 2012

Я предполагаю, что вы используете SQL?

Lithium в основном предназначен для баз данных noSQL, поэтому рекурсивность / мультисоединения не являются целью проектирования.

  • Вы можете установитьсоздать собственный SQL-запрос на соединение и привести его к модели.
  • запросить город с помощью Users и State в качестве объединений.
  • вы можете настроить представление объединения на основе базы данных, и li3 использует его какотдельная модель.
  • вам, вероятно, следует разбить запланированный рекурсивный вызов на несколько запросов в дБ.

Подумайте об отношении n городов к m государствам.=> получить пользователя с указанием города, а затем штата по идентификатору штата.=> передать это как два ключа или внедрить информацию о состоянии.Это было бы приемлемо для запросов Users :: all () aswell.

Пример использования Lithiums util \ Set Class:

use \lithium\util\Set;
$users = Users::all(..conditions..);
$state_ids = array_flip(array_flip(Set::extract($users->data(), '/city/state_id')));
$stateList = States::find('list',array(
    'conditions' => array(
        'id' => $state_ids
    ),
));
2 голосов
/ 09 июня 2012

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

class Users extends \lithium\data\Model {
    public $belongsTo = array(
        "Cities" => array(
            "to" => "app\models\Cities",
            "key" => "city_id",
        ),
        "States" => array(
            "from" => "app\models\Cities",
            "to" => "app\models\States",
            "key" => array(
                "state_id" => "id", // field in "from" model => field in "to" model
            ),
        ),
    );
}

class Cities extends \lithium\data\Model {
    public $belongsTo = array(
        "States" => array(
            "to" => "app\models\States",
            "key" => "state_id",
        ),
    );
}

class States extends \lithium\data\Model {
    protected $_meta = array(
        'key' => 'id',  // notice that this matches the value 
                        // in the key in the Users.States relationship
    );
}

При использовании отношений Состояния на Пользователях обязательно всегда указывайтеотношения городов в том же запросе.Например:

Users::all( array( 
    'with' => array(
        'Cities', 
        'States'
    ) 
) ); 

Я никогда не пробовал это с использованием отношений ownTo, но у меня это работает, используя отношения hasMany таким же образом.

...