Пагинация с ассоциацией hasMany cakePHP
-
22-09-2019 - |
Вопрос
У меня есть две таблицы:
Участник и участник голоса Hasmany голосует
Я пытался сделать счет (голосовать.Я сделал это на массиве полей, но это дало мне общее количество голосов, независимо от того, к чему участника, к которому они принадлежат.
Голоса связаны вместе в сфере записей участника, поэтому, по моему мнению, я сделал счет ($ Cantagant [голосовать]), но это нельзя быть на страже, и мой клиент хочет иметь возможность сортировать участников по голосам.
Есть ли способ сделать что-то подобное, на мой взгляд?:
sort('Голоса', 'подсчет(Голосование)');?>
Или мне нужно создать запрос, который делает подсчет всех голосов, где участник.
Участник контролера:
function index() {
$page = 'Contestants';
$this->set('page', $page);
$this->paginate =
array(
'order' => 'id ASC',
'contain' => array(
'Vote' => array(
'fields' => array("Vote.contestant_id",'Vote.id')
)
)
$conditions ["Contestant.active"] = 1;
$this->set('contestants', $this->paginate('Contestant',
$условия));}
Решение 2
Поскольку cakephp не поддерживает группировку по вмещаемому поведению, я попробовал другой подход.Вместо этого создайте переменную paginate для модели голосования (все это делается в контроллере участников):
var $paginate = array(
'Vote'=>array(
'limit'=>5,
'fields' => array(
'Contestant.*, count(Vote.contestant_id) as Contestant_votes, Vote.id'
),
'group' => array(
'Vote.contestant_id'
),
'order' => array(
'Contestant_votes Desc'
)
),
'Contestant'=>array(
'limit'=>5,
'order' => array(
'Contestant.id Desc'
)
)
);
И теперь в моем контроллере я делаю следующее:
function index() {
$page = 'Contestants';
$this->set('page', $page);
$conditions ["Contestant.active"] = 1;
$this->set('contestants', $this->paginate($this->Contestant->Vote,$conditions));
}
Теперь участники упорядочены по общему количеству голосов, хотя я до сих пор не могу понять, как разместить Contestant_votes в качестве переменной разбивки на страницы, поскольку в наборе записей она находится в собственном массиве, а не в каком-либо из массивов модели, используемых для разбивки на страницы. .
Спасибо, Мэтт Хаггинс, именно ваш подход привел меня к этому решению.
Другие советы
Посмотрите ответ deceze на этот вопрос: Поле математических вычислений CakePHP?
По сути, вы хотите сделать что-то вроде этого, я предполагаю:
'contain' => array(
'Vote' => array(
'fields' => array('SUM(Vote.id) AS Contestant__votes'),
'group' => array('Vote.contestant_id'),
)
)
Добавление:Вы также хотите отсортировать по голосам (общему количеству голосов) по возрастанию или убыванию?Если да, то вы не сможете легко сделать это с помощью метода разбиения на страницы по умолчанию в cakephp.
Для этого вам нужно немного подправить.Вот подробности об этом трюке: CakePHP Advanced Pagination – сортировка по производному полю
Надеюсь, вы найдете это полезным.
Спасибо Аднану
В конкретных отношениях, которые вы определяете, ваши потребности хорошо удовлетворяются контркэширование.
Вам нужно будет определить новое поле в вашем contestants
стол: vote_count
.Затем в вашей модели голосов вам необходимо обновить $belongsTo
определение немного:
class Votes extends AppModel
{
var $belongsTo = array(
'Contestant' => array( 'counterCache' => true )
);
}
Теперь при каждом сохранении записи голосования vote_count
поле родительского участника будет обновлено.Теперь вы можете просто сортировать по Contestant.vote_count
как и в любом другом поле участника:
class ContestantsController extends AppController
{
// Controller stuff that comes before...
function index()
{
$this->paginate = array( 'Contestant' => array(
'conditions' => array( 'Contestant.active' => 1 ),
'order' => array( 'Contestant.vote_count' => 'DESC' ),
));
$contestants = $this->paginate('Contestants');
$this->set( compact('contestants'));
}
// Controller stuff that comes after...
}