CakePHP对包含数据进行分页排序

CakePHP对包含数据进行分页排序,php,mysql,cakephp,pagination,paginator,Php,Mysql,Cakephp,Pagination,Paginator,这是一个跟踪用户爱好的简单应用程序。用户可以有许多爱好,这些爱好被组织成不同的爱好组 所以我有4个相关的表格:用户,用户的业余爱好,业余爱好,业余爱好组 用户是一个拥有并属于许多与爱好相关的人,通过用户爱好联接表。 爱好属于爱好小组,爱好小组有很多爱好 有道理,到目前为止相当简单 在UsersHobbiesController中,我有: $paginate = [ 'contain' => [ 'Hobby' => [ 'fields'

这是一个跟踪用户爱好的简单应用程序。用户可以有许多爱好,这些爱好被组织成不同的爱好组

所以我有4个相关的表格:用户用户的业余爱好业余爱好业余爱好组

用户是一个拥有并属于许多与爱好相关的人,通过用户爱好联接表。 爱好属于爱好小组,爱好小组有很多爱好

有道理,到目前为止相当简单

在UsersHobbiesController中,我有:

$paginate = [
    'contain' => [
        'Hobby' => [
            'fields' => ['id', 'name'],
            'HobbyGroup' => [
                'fields' => ['id', 'name']
            ]
        ]
    ]
];
另外,在我的index()函数中,我构建了分页

$usersHobbies = $this->paginate('UsersHobby');
$this->set(compact('usersHobbies));
当我访问index.ctp视图文件中的$usersHobbies变量时,它包含了构建输出表所需的数据。它看起来像:

array(
    (int) 0 => array(
        'UsersHobby' => array(...),
        'Hobby' => array(
            'id' => 'abc-def-ghi',
            'name' => 'Jet Skiing',
            'HobbyGroup' => array(
                'id' => 'oiuy-trew-qldf',
                'name' => 'Watersports'
            )
        )
    )
    ....
)
为了对输出表进行排序,我添加了一些排序列:

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

第一个标题用于对爱好名称进行排序。但是我不能得到第二个标题来为HobbyGroup排序。有没有一个简单的方法可以做到这一点


我在StackOverflow上搜索了几个小时,但似乎找不到适合我的答案。谢谢。

由于CakePHP是如何获取数据的,所以这不会像您期望的那样工作

根据你建立关系的方式,将发生的情况是,蛋糕将首先选择爱好,然后对爱好组执行另一个查询

因此,当数据映射到兴趣爱好列表时,应用于第二个查询的任何排序通常都是无用的和丢失的

你有吗

选择爱好….

然后将发出另一个select

选择hooby_组,其中hooby_id在[id列表]中按hobby_组id排序

第二个select的数据将映射到第一个select,因此您的orderby没有做多少工作

根据您使用的CakePHP版本,您可以做以下几件事:

  • 定义要使用
    内部联接
    策略的关系,以避免创建两个
    SELECT
    语句。这样,
    orderby
    cause将按照您的期望对所有数据进行排序。需要注意的是,使用
    内部连接
    时,分页将永远不会选择没有任何组关联的爱好

  • 如果您使用的是CakePHP 2.x,您可以根据需要查看并构建查询,以使其正常工作

  • 如果您使用的是CakePHP 3.x,那么那里有一个查询生成器,Paginator可以对任何查询进行分页,因此您可以在那里进行内部联接

  • 为了帮助您,您可以使用CakePHP中的
    DebugKit
    ,查看实际运行的查询以及调整此参数和该参数如何影响查询的生成。您将看到在哪里应用了order by,以及它可能不起作用的原因


    在cakephp2.x中,可以使用
    键入
    来控制连接的方式。您需要使用
    内部

    谢谢您的回答,它帮助我找到了正确的方向。实际上,我调整了$paginate变量,使用左连接而不是contain(我将已连接的User嗜好留给了用户,留给了嗜好,留给了HobbyGroup),这使得HobbyGroup可以直接在返回结果中进行排序。在调用paginate()函数时,我还必须添加一个包含所有要排序的列的数组作为白名单参数,以便仅在HobbyGroup.id上启用排序,这一切都开始起作用。