cakephp - 按分页中的二级关联排序

时间:2011-01-29 14:39:30

标签: php cakephp cakephp-1.3 paginate

我正在玩一个与我跑的滑雪旅行有关的报价数据库。我试图列出引号,但按说出引用的人排序,我正在努力让分页助手让我这样做。

我有四张相关的表格。

报价,旅行,人员和出勤率。出勤本质上是人和旅行的连接表。

关系如下;

出勤属于人有多人出席 出勤属于旅行有很多人出席 出勤有很多报价属于出勤

在QuotesController中,我使用containsable来检索Quote中的字段,以及相关的Attendance,以及与该出席相关的Trip和Person中的字段。

function index() {
   $this->Quote->recursive = 0;
   $this->paginate['Quote'] = array(
   'contain' => array('Attendance.Person', 'Attendance.Trip'));
   $this->set('quotes', $this->paginate());
}

这似乎工作正常,在视图中,我可以回应

foreach ($quotes as $quote) {
echo $quote['Attendance']['Person']['first_name'];
}

没有任何问题。

我无法工作的是访问/使用与paginate

中的排序字段相同的变量
 echo $this->Paginator->sort('Name', 'Attendance.Person.first_name');

echo $this->Paginator->sort('Location', 'Attendance.Trip.location');

不起作用。它似乎按某种东西排序,但我不确定是什么。

我传递的$ quotes数组看起来像这样;

Array
(
     [0] => Array
            (
                [Quote] => Array
                     (
                        [id] => 1
                        [attendance_id] => 15
                        [quote_text] => Hello

            )

                [Attendance] => Array
            (
                        [id] => 15
                        [person_id] => 2
                        [trip_id] => 7
                        [Person] => Array
                             (
                              [id] => 2
                              [first_name] => John
                              [last_name] => Smith

                               )

                        [Trip] => Array
                             (
                              [id] => 7
                              [location] => La Plagne
                              [year] => 2000
                              [modified] => 
                         )

                 )

         )

如果有人能够建议我如何通过与Quote相关联的Person的first_name进行排序,我将非常感激。我怀疑我的语法错了,但我找不到答案。是不是可以通过这种方式按二级关联进行排序?

我对cakephp非常陌生,所以请保持温和。

非常感谢。

3 个答案:

答案 0 :(得分:1)

我早就遇到过类似的问题了。虽然没有排序。尝试将关联的表放在另一个数组中。

echo $this->Paginator->sort('Name', 'Attendance.Person.first_name');

更改为:

echo $this->Paginator->sort('Name', array('Attendance' => 'Person.first_name'));

希望这有帮助

答案 1 :(得分:0)

我也在寻求帮助。

到目前为止,我发现在使用可链接插件https://github.com/Terr/linkable之后,您可以在控制器的分页选项中对多级关联进行排序。 但是当您尝试在视图中对分页器进行排序时会出现故障。我正在使用控制器进行杂志剪报。每个剪辑都属于一个问题,每个问题都属于一个出版物。

    $this->paginate = array(
        "recursive"=>0,
        "link"=>array("Issue"=>array("Publication")),
        "order"=>array("Publication.name"=>"ASC",
        "limit"=>10);

调试$ this-> Paginator-> params-> paging->在视图中剪切后,您可以看到排序在两个单独的位置描述,“默认值”和“选项”。排序信息需要同时存在才能在视图中工作。 这是在控制器中设置顺序之后:

[Clipping] => Array
            (
                [page] => 1
                [current] => 10
                [count] => 6685
                [prevPage] => 
                [nextPage] => 1
                [pageCount] => 669
                [defaults] => Array
                    (
                        [limit] => 10
                        [step] => 1
                        [recursive] => 0
                        [link] => Array
                            (
                                [Issue] => Array
                                    (
                                        [0] => Publication
                                    )

                            )

                        [order] => Array
                            (
                                [Publication.name] => ASC
                            )

                        [conditions] => Array
                            (
                            )

                    )

                [options] => Array
                    (
                        [page] => 1
                        [limit] => 10
                        [recursive] => 0
                        [link] => Array
                            (
                                [Issue] => Array
                                    (
                                        [0] => Publication
                                    )

                            )

                        [order] => Array
                            (
                                [Publication.name] => ASC
                            )

                        [conditions] => Array
                            (
                            )

                    )

            )

这是在使用$ this-> Paginator-> sort(“Publication”,“Publication.name”);.

之后

注意options数组是空的。

[Clipping] => Array
            (
                [page] => 1
                [current] => 10
                [count] => 6685
                [prevPage] => 
                [nextPage] => 1
                [pageCount] => 669
                [defaults] => Array
                    (
                        [limit] => 10
                        [step] => 1
                        [recursive] => 0
                        [link] => Array
                            (
                                [Issue] => Array
                                    (
                                        [0] => Publication
                                    )

                            )

                        [order] => Array
                            (
                                [Publication.name] => DESC
                            )

                        [conditions] => Array
                            (
                            )

                    )

                [options] => Array
                    (
                        [page] => 1
                        [limit] => 10
                        [recursive] => 0
                        [link] => Array
                            (
                                [Issue] => Array
                                    (
                                        [0] => Publication
                                    )

                            )

                        [order] => Array
                            (
                            )

                        [conditions] => Array
                            (
                            )

                    )

是否真的需要修改paginator类才能使其工作?


<强>更新


我发现了问题: 在核心蛋糕控制器paginator中合并默认值和选项以创建查找查询。 但是当使用linkable进行排序时,options数组为空。因为选项在默认情况下列出,它会覆盖默认值,空数组会替换默认的选项数组。 解决方法是扩展app_controller.php中的paginate函数,如果为空,则取消设置options数组顺序值: (cake / libs / controller / controller.php中的第1172行)

if(empty($options["order"])){
unset($options["order"]);
}

然后这些选项不会被空白数组覆盖。 当然这不应该在controller.php中更改,而是将其放在app_controller.php中并将其移动到您的app文件夹。

答案 2 :(得分:0)

在CakePHP 3上,可以通过在控制器上向'sortWhitelist'添加$this->paginate参数来解决此问题。

$this->paginate = [
    // ...
    'sortWhitelist' => ['id', 'status', 'Attendance.Person.first_name']
];

然后在你看来:

echo $this->Paginator->sort('Name', 'Attendance.Person.first_name');

注意到in the docs

  

如果要对任何关联数据或可能属于您的分页查询的计算字段进行排序,则需要此选项:

然而,疲惫的双眼很容易错过,所以希望这可以帮助那些人!