Можно ли получить доступ к более чем одной модели в отношениях между литиями?
Например, у меня есть модель User:
class Users extends \lithium\data\Model { public $validates = array(); public $belongsTo = array("City"); }
и у меня есть модель города:
class Cities extends \lithium\data\Model { public $validates = array(); public $belongsTo = array("State"); }
и модель государства, и так далее.
Если я запрашиваю пользователя, с чем-то похожим на Users::first()
, можно ли получить все отношения, включенные в результаты? Я знаю, что могу делать Users::first(array('with' => 'City'))
но я бы хотел, чтобы каждый City также возвращал свою модель State, поэтому я могу получить к нему доступ следующим образом:
$user->city->state->field
Прямо сейчас я могу заставить его пойти один глубокий ( $user->city
), и мне придется снова потребовать, что кажется неэффективным.
Я предполагаю, что вы используете SQL?
Литий в основном предназначен для noSQL db's, поэтому рекурсивность / множественные соединения не являются целью дизайна.
Подумайте о коэффициенте n городов для m государств. => выберите пользователя с городом, а затем состояние с идентификатором состояния. => передать это как два ключа или вставить информацию о состоянии. Это было бы приемлемо для запросов Users :: all ().
Пример использования 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 ), ));
Используя недавнего мастера, вы можете использовать следующие вложенные обозначения:
Users::all( array( 'with' => array( 'Cities.States' ) ));
Он будет делать JOINs для вас.
Вы можете настроить отношения таким образом, но вам нужно использовать более подробное определение отношений. Посмотрите на данные, которые передаются при построении отношения для получения подробных сведений о параметрах, которые вы можете использовать.
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 ); }
При использовании отношений States для пользователей обязательно включайте отношения Cities в том же запросе. Например:
Users::all( array( 'with' => array( 'Cities', 'States' ) ) );
Я никогда не пробовал это с использованием отношений belongsTo, но у меня есть работа с использованием отношений hasMany таким же образом.