CakePHP - paginate and sort 2nd level association

て烟熏妆下的殇ゞ 提交于 2019-12-01 06:23:51

问题


I understand that this has been asked 100,000 times but I've pretty much read all 100,000 replies and none of them seem to match what I'm after. I've tried every possible combination (obviously not) and I'm afraid I'm getting beat at something so relatively simple. This is my 2nd Cake project, so I'm by no means an expert.

Profile -> BelongsTo -> Store, Store -> BelongsTo -> Region, Region -> HasMany -> Stores

Profile.php

class Profile extends AppModel {  
public $belongsTo = array(
            'Store' => array(
                'className' => 'Store',
                'foreignKey' => 'store_id'....

Store.php

class Store extends AppModel {
public $belongsTo = array(
        'Region' => array(
            'className' => 'Region',
            'foreignKey' => 'region_id'....

Region.php

class Region extends AppModel {
public $hasMany = array(
        'Store' => array(
            'className' => 'Store',
            'foreignKey' => 'region_id'....

ProfileController.php

$this->Paginator->settings = array(
    'conditions' => array('Profile.job_title_id' => '1'),
    'contain' => array(
        'Store'=> array(
            'Region'
        )
    )
);
$UserArds = $this->Paginator->paginate('Profile');
$this->set(compact('UserArds'));

view.php

<th><?php echo $this->Paginator->sort('Region.name', 'Region'); ?></th>

All I'm looking to do, is to be able to sort by Region name when using paginator. No matter what combination I use, I just can't seem to be able to sort Region.name. The order By clause is omitted with all other 2-level-deep associations but works fine any other time (with same level or 1st level).

Can anyone suggest a fix for this simple mistake?


回答1:


Look at the SQL debug output, the regions are being retrieved using separate queries, that's how Cakes ORM currently works.

In your case there's a relatively simple workaround. Just create a proper association on the fly, for example Profile belongsTo Region.

Here's an (untested) example, it adds a belongsTo association with the foreignKey option set to false in order to disable the automatic foreign key generation by the ORM, this is necessary as it would otherwise look for something like Profile.region_id. Note that consequently the contain config has to be changed too!

$this->Profile->bindModel(array(
    'belongsTo' => array(
        'Region' => array(
            'foreignKey' => false,
            'conditions' => array('Region.id = Store.region_id')
        ),
    )
));

$this->Paginator->settings = array(
    'conditions' => array('Profile.job_title_id' => '1'),
    'contain' => array('Store', 'Region')
);

That should generate a proper query that includes the stores as well as the regions table, making it possible to sort on Region.name. Note that the resulting array will be a little different, Region will not be nested in Store, everything will be placed in the same level, ie:

Array
(
    [Profile] => Array
        (
            ....
        )

    [Store] => Array
        (
            ....

        )

    [Region] => Array
        (
            ....

        )
)

Either you modify your view code accordingly, or you transform the retrieved data before passing it to the view. A third option would be to include a nested Region in the contain config, however that would result in additional queries that are totally unnecessary as the data was already fetched with the main query, so I wouldn't recommend that.




回答2:


Great answer. I used it. To try generalise it for other users :

$this->FirstLevel->bindModel(array(
    'belongsTo' => array(
        'SecondLevel' => array(
            'foreignKey' => false,
            'conditions' => array('SecondLevel.firstLevel_id = FirstLevel.id')
        ),
    )
));

$this->Paginator->settings = array(
    //'conditions' => $retrieveDataCondition,
    'contain' => array('SecondLevel')
);
$data = $this->Paginator->paginate('FirstLevel');


来源:https://stackoverflow.com/questions/18958410/cakephp-paginate-and-sort-2nd-level-association

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