【问题标题】:CakePHP -- conditions ignored when using paginate() twice in a single actionCakePHP -- 在一个动作中使用两次 paginate() 时忽略条件
【发布时间】:2012-03-29 16:58:12
【问题描述】:

我有一个基于 CakePHP 2.0 的照片博客,其数据结构如下:

POSTS <-habtm-> TAGS <-habtm-> IMAGES

我正在构建一个基于 AJAX 的功能来查找与给定标签匹配的所有博客文章和图像。首次选择标签时,帖子的第 1 页和图像的第 1 页将加载到相邻的面板中。之后,它们可以独立地进行分页。在大多数情况下,这工作正常,除非我正在获取初始数据页。

我在第一次操作中使用了两次paginate()——一次是为了获取我的帖子,第二次是为了获取图片。问题是我为序列中的第二个模型分配给paginate() 的条件被完全忽略了。单独他们都工作正常,并且切换他们的顺序已经证实这对我来说是一个依赖于序列的问题,而不是仅限于一个模型或另一个。

我已经搜索过过去是否有其他人遇到过类似的问题,但这要么是我的一个不寻常的设计选择,要么我没有找到正确的搜索查询。

我的基本$paginate 数组在我的TagsController.php 中声明如下:

public $paginate = array(
    "PostsTag" => array(
        "limit" => 4,
        "order" => "Post.id DESC",
        "contain" => array(
            "Tag",
            "Post" => array("fields" => array(
                "id", "title", "created"))
        ),
        "group" => array("Post.id")
    ),
    "ImagesTag" => array(
        "limit" => 4,
        "order" => "Image.id DESC",
        "contain" => array(
            "Tag",
            "Image" => array("fields" => array(
                "id", "title", "url", "created", "gallery"))
        ),
        "group" => array("Image.id")
    )
);

在我的主要搜索操作中,我调用了两个私有函数:

$posts = $this->post_pagination($tagIds);

$images = $this->image_pagination($tagIds);

将限制条件添加到$paginate,如下所示:

private function post_pagination($tags, $page = 1) {
    $this->paginate['PostsTag']['conditions'] = array(
        "status" => 1,
        "OR" => array("tag_id" => $tags)
    );
    $this->paginate['PostsTag']['page'] = $page;
    return $this->paginate("PostsTag");
}

private function image_pagination($tags, $page = 1) {
    $this->paginate['ImagesTag']['conditions'] = array(
        "gallery" => 1,
        "OR" => array("tag_id" => $tags)
    );
    $this->paginate['ImagesTag']['page'] = $page;
    return $this->paginate("ImagesTag");
}

Cake 尊重 limitordercontain 等,没有问题,但将球放在 conditions 上,特别是对于我尝试在第二个页面上分页的任何模型。它反馈给我正确排序的前 4 个结果,但完全未经过滤。我也不认为我有点复杂的conditions 有问题——只要我不破坏语法,我可以在conditions 中输入完全随机的字符串,第二个paginate() 得到相同的结果。

非常感谢任何帮助或建议。

[编辑] 这是第二个paginate() 查询的 SQL 转储:

SELECT `PostsTag`.`id`, `PostsTag`.`post_id`, `PostsTag`.`tag_id`, 
`Tag`.`id`, `Tag`.`name`, `Post`.`id`, `Post`.`title`, `Post`.`created` 
FROM `posts_tags` AS `PostsTag` 
LEFT JOIN `tags` AS `Tag` ON (`PostsTag`.`tag_id` = `Tag`.`id`) 
LEFT JOIN `posts` AS `Post` ON (`PostsTag`.`post_id` = `Post`.`id`) 
WHERE 1 = 1 
GROUP BY `Post`.`id` 
ORDER BY `Post`.`id` 
DESC LIMIT 4

如您所见,Cake 正在生成 WHERE 1 = 1 来代替我的条件。

【问题讨论】:

  • 您是否尝试过在条件数组中使用'Model.field' => val 而不仅仅是'field' => val?所以就像PostTag.status 等。
  • 你知道,在我睡眼惺忪的那天晚上,我什至没有注意到我忽略了为其中一些条件指定模型,所以谢谢你让我注意到这一点。但是,问题仍然存在。现在我刚刚为第二个 paginate() 手动组装了一个直接的 SQL 查询,它工作正常。虽然我遇到的问题仍然让我感到困惑。

标签: cakephp conditional-statements pagination


【解决方案1】:

来自未来的亲爱的人们:这就是我们目前所发现的......

OP 是正确的,YourController::$paginate 只被送入PaginatorComponent 一次。如果您需要使用不同的选项再次调用YourController::paginate(),则需要先卸载组件,例如:

$this->Components->unload('Paginator');

然后,下次您调用 YourController::paginate() 时,它将重新加载 YourController::$paginate 属性中的所有内容。

【讨论】:

    【解决方案2】:

    因此,经过更多的探索,我发现了以下内容:

    在初始paginate() 调用后对$paginate 所做的任何更改都不会传递到Paginator 组件。这适用于conditionsorderlimit 等。

    这样做:

    $this->paginate['<model1>']['conditions'] = array( ... );
    $model1Results = $this->paginate("<model1>");
    
    $this->paginate['<model2>']['conditions'] = array( ... );
    $model2Results = $this->paginate("<model2>");
    

    将返回&lt;model1&gt; 的结果,这些结果符合新条件/订单/限制/您应用的任何内容,但您的&lt;model2&gt; 结果将基于$paginate 中为其定义的原始条件。你的控制器会看到$paginate 的更新就好了,但似乎$paginate 只能被Paginator 抓取一次。

    我发现的解决方法是在第一次调用paginate() 之前对$paginate 进行所有更改,所以:

    $this->paginate['<model1>']['conditions'] = array( ... );
    $this->paginate['<model2>']['conditions'] = array( ... );
    
    $model1Results = $this->paginate('<model1>');
    $model2Results = $this->paginate('<model2>');
    

    我一直在PaginatorComponent.php 中四处寻找,以找出为什么会这样,当然,如果有任何进一步的见解,我们将不胜感激。

    【讨论】:

      猜你喜欢
      • 2013-08-29
      • 2011-01-14
      • 1970-01-01
      • 2019-06-02
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 1970-01-01
      • 2020-12-14
      相关资源
      最近更新 更多