Search code examples
phplithium

Accessing more than one model deep relationships in Lithium


Is it possible to access more than one model deep in a relationship in Lithium?

For example, I have a User model:

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

and I have a City model:

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

and a State model, and so on.

If I'm querying for a User, with something similar to Users::first(), is it possible to get all the relationships included with the results? I know I can do Users::first(array('with' => 'City')) but I'd like to have each City return its State model, too, so I can access it like this:

$user->city->state->field

Right now I can only get it to go one deep ($user->city) and I'd have to requery again, which seems inefficient.


Solution

  • I am guessing you are using SQL?

    Lithium is mainly designed for noSQL db´s, so recursiveness / multi joins are not a design goal.

    • You could set up a native sql join query and cast it on a model.
    • query the city with Users and State as joins.
    • you could setup a db based join view and li3 is using it as a seperate model.
    • you probably should split your planned recursive call into more than one db requests.

    Think about the quotient of n Cities to m States. => fetch the user with city and then the state by the state id. => pass that as two keys or embed the state info. This would be acceptable for Users::all() queries aswell.

    Example using 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
        ),
    ));