分页器未传递 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');
当然还有计数器缓存行为。
另见
- Cookbook > Database Access & ORM > Query Builder > Adding Calculated Fields
- Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Modifying Results with Map/Reduce
- Cookbook > Database Access & ORM > Query Builder > Using leftJoinWith
- Cookbook > Database Access & ORM > Behaviors > CounterCache
我的 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');
当然还有计数器缓存行为。
另见
- Cookbook > Database Access & ORM > Query Builder > Adding Calculated Fields
- Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Modifying Results with Map/Reduce
- Cookbook > Database Access & ORM > Query Builder > Using leftJoinWith
- Cookbook > Database Access & ORM > Behaviors > CounterCache