Accessing more than one model deep relationships in Lithium

我是研究僧i 提交于 2019-12-04 09:38:13

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

Using a recent master you can use the following nested notation:

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

It will do the JOINs for you.

You can set up relationships in this way, but you have to use a more verbose relationship definition. Have a look at the data that gets passed when constructing a Relationship for details about the options you can use.

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
    );
}

When using the States relationship on Users, be sure to always include the Cities relationship in the same query. For example:

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

I have never tried this using belongsTo relationships, but I have it working using hasMany relationships in the same way.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!