这是一个用于跟踪用户爱好的简单应用程序。一个用户可以有很多爱好,这些爱好被组织成不同的爱好组。
所以我有 4 个相关表:users、users_hobbies、hobbies、hobby_groups。
通过 users_hobbies 连接表,users 是与爱好的拥有和属于多的关系。 hobbies belongs-to a hobby_group, hobby_group has-many hobbies
有道理,到目前为止非常简单。
在 UsersHobbiesController 中,我有:
$paginate = [
'contain' => [
'Hobby' => [
'fields' => ['id', 'name'],
'HobbyGroup' => [
'fields' => ['id', 'name']
]
]
]
];
此外,在我的 index() 函数中,我构建了分页。
$usersHobbies = $this->paginate('UsersHobby');
$this->set(compact('usersHobbies));
当我访问我的 index.ctp View 文件中的 $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>
第一个 header 用于根据爱好名称进行排序。但我无法获取第二个 header 来为 HobbyGroup 排序。有没有简单的方法可以做到这一点?
我在 StackOverflow 上搜索了几个小时,但似乎找不到适合我的答案。谢谢。
最佳答案
由于 CakePHP 获取数据的方式,这不会像您预期的那样工作。
根据您设置关系的方式,Cake 将首先选择兴趣爱好,然后然后再次查询兴趣爱好组。
因此,当该数据映射到爱好列表时,您应用于第二个查询的任何排序通常都是无用的并且会丢失。
所以你有
选择爱好....
然后将发出另一个选择
SELECT hooby_groups WHERE hobby_id IN [list of ids] ORDER BY hobby_groups_id
来自第二个选择的数据将映射到第一个,所以你的 order by 没有做太多!
根据您使用的 CakePHP 版本,您可以做几件事:
定义使用
INNER JOIN
策略的关系,这样可以避免创建两个SELECT
语句。这样order by
原因将按照您的预期对所有数据进行排序。需要注意的是,使用INNER JOIN
没有任何关联组的兴趣爱好永远不会被您的分页选中。如果您使用的是 CakePHP 2.x,您可以查看 Custom Query Pagination并根据需要构建查询以使其正常工作。
如果您使用的是 CakePHP 3.x,则那里有一个查询构建器,分页器可以对任何查询进行分页,因此您可以在那里进行内部联接。
为了帮助您解决问题,您可以使用 CakePHP 的 DebugKit
来查看正在运行的实际查询以及调整此参数和那个参数如何影响查询的生成方式。您将看到应用 order by
的位置以及它可能不起作用的原因。
在 CakePHP 2.x 中,您可以使用 type
来控制连接的完成方式。你需要使用 INNER
关于php - CakePHP 分页排序包含数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50282609/