分页器未传递 CakePHP 自定义字段

CakePHP custom field not passed by paginator

我的 PhotoalbumsModel

中有这个方法
public function index_list()
{
    $data = $this->find()
    ->contain(['Images' => function($q) {
            $q->select([
                 'total' => $q->func()->count('image_id')
            ])
            ->group(['photoalbum_id']);
            return $q;
        }
    ]);

    foreach ($data as $row)
    {
        $row->image_count = 0;
        if (isset($row->images{0}->total))
        {
            $row->image_count = $row->images{0}->total;
        }
        unset($row->images);
    }       
    return $data;
}

这基本上将 image_count 添加到行中。

在我的控制器中我使用:

<?php
class PhotoalbumsController extends AppController
{
    public $paginate = [
        'limit' => 2,
        'order' => ['id' => 'desc']
    ];

    public function index()
    {
        $photoalbums = $this->paginate($this->Photoalbums->index_list());
        $this->set(compact('photoalbums'));
    }

但是,在我看来image_count没有通过。不使用分页器就通过了。

我该如何解决这个问题?

分页器将选项应用于查询,例如限制,这将导致查询被标记为脏,这反过来又清除了任何可能缓冲的结果集,所以你在那里做的是迭代 a 是删除结果集,修改对象(实体)将无处可去。

你根本不应该依赖缓冲的结果集,如果你需要可靠地修改查询结果,那么你应该使用结果格式化程序或 map/reduce,它们都应用于结果每次执行查询时:

$query = $this
    ->find()
    ->contain([
        'Images' => function($q) {
            $q
                ->select([
                    'total' => $q->func()->count('image_id')
                ])
                ->group(['photoalbum_id']);

            return $q;
        }
    ])
    ->formatResults(function (\Cake\Collection\CollectionInterface $results) {
        return $results->map(function ($row) {
            $row['image_count'] = $row['images'][0]['total'];

            return $row;
        });
    });

return $query;

也就是说,您也可以直接在 SQL 级别处理此问题,方法是加入关联而不是包含它,然后在主查询中选择列:

$query = $this->find();
$query
    ->select(['image_count' => $query->func()->count('Images.id')])
    ->enableAutoFields()
    ->leftJoinWith('Images')
    ->group('Photoalbums.id');

当然还有计数器缓存行为。

另见