CakePHP - 分页和排序第二级关联

时间:2013-09-23 11:46:00

标签: cakephp pagination cakephp-2.3

据我所知,这已被问过10万次,但我几乎已经阅读了所有10万份回复,但这些回复似乎与我所追求的不相符。我已经尝试了所有可能的组合(显然不是),我担心我会因为相对简单的事情而受到打击。这是我的第二个蛋糕项目,所以我绝不是专家。

个人资料 - > 属于 - >商店,商店 - > 属于 - >地区,地区 - > HasMany - >存储

配置文件 .PHP

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

商品 .PHP

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

区域 .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'));

查看 .PHP

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

我想要做的就是能够在使用paginator时按区域名称排序。无论我使用什么组合,我似乎无法对Region.name进行排序。所有其他2级深度关联都省略了order By子句,但在任何其他时间(具有相同级别或第1级别)都可以正常工作。

有人能建议修复这个简单的错误吗?

2 个答案:

答案 0 :(得分:7)

查看SQL调试输出,使用单独的查询检索区域,这就是Cakes ORM当前的工作方式。

在您的情况下,有一个相对简单的解决方法。只需create a proper association on the fly,例如Profile belongsTo Region

这是一个(未经测试的)示例,它添加belongsTo关联,foreignKey选项设置为false,以禁用ORM生成的自动外键,这是必要的因为它会寻找像Profile.region_id这样的东西。请注意,因此contain配置也必须更改!

$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')
);

这应生成包含storesregions表的正确查询,从而可以对Region.name进行排序。请注意,生成的数组会有所不同,Region不会嵌套在Store中,所有内容都将放在同一级别,即:

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

    [Store] => Array
        (
            ....

        )

    [Region] => Array
        (
            ....

        )
)

您可以相应地修改视图代码,也可以在将检索到的数据传递给视图之前对其进行转换。第三种选择是在Region配置中包含嵌套的contain,但这会导致额外的查询完全不必要,因为数据已经使用主查询获取,所以我不会推荐。

答案 1 :(得分:1)

很棒的答案。我用过它。尝试将其概括为其他用户:

$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');