Paginação com Hasmany Association Cakephp
-
22-09-2019 - |
Pergunta
Eu tenho duas mesas:
Participante e participante dos votos Hasmany Votos
Eu tentei fazer uma contagem (vote.id) como votos para que eu possa colocá -lo no registro e apenas paginá -los, mas não tenho idéia de onde colocá -lo. Eu fiz isso na matriz de campos, mas isso me deu a contagem total de votos, independentemente do concorrente que eles pertencem.
Os votos estão vinculados no concorrente, então o que eu fiz foi, na minha opinião, fiz uma contagem ($ participante [voto]), mas isso não pode ser paginado e meu cliente quer ser capaz de classificar os participantes por votos.
Existe uma maneira de fazer algo assim na minha opinião?:
Sort ('Votos', 'Count (Vote)'); ?>
Ou eu tenho que criar uma consulta que seja uma conta para todos os votos onde o competidor.id = votos.contestant_id?
Concorrente do controlador:
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',
$ condições)); }
Solução 2
Como o CakePHP não suporta o grupo em comportamento em contagem, tentei uma abordagem diferente. Crie o VAR paginato para o modelo de voto (tudo isso é feito no Controlador dos Concorrentes):
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'
)
)
);
E agora no meu controlador eu faço o seguinte:
function index() {
$page = 'Contestants';
$this->set('page', $page);
$conditions ["Contestant.active"] = 1;
$this->set('contestants', $this->paginate($this->Contestant->Vote,$conditions));
}
Agora, os participantes são ordenados pelo seu total de voto, embora eu ainda não consiga descobrir como colocar os concorrentes_votes como uma variável de paginador, pois no conjunto de registros está em uma matriz própria e não em nenhuma das matrizes de modelo usadas para paginar .
Obrigado Matt Huggins Sua abordagem foi a que me levou a essa solução.
Outras dicas
Confira a resposta de DeCeze nesta pergunta: Campo de cálculo matemático Cakephp?
Essencialmente, você quer fazer algo assim, estou supondo:
'contain' => array(
'Vote' => array(
'fields' => array('SUM(Vote.id) AS Contestant__votes'),
'group' => array('Vote.contestant_id'),
)
)
Adição: você também deseja classificar por votos (totais de votos) ascendentes ou descendentes? Se sim, você não pode fazê -lo facilmente pelo método de paginação padrão do CakePhp.
Para isso, você precisa de um pequeno ajuste. Aqui estão os detalhes sobre este truque: Paginação avançada de CakePhp - classificar por campo derivado
Espero que você ache isso útil.
Obrigado Adnan
Para o relacionamento específico que você define, suas necessidades estão bem atendidas por contra-cache.
Você precisará definir um novo campo em seu contestants
tabela: vote_count
. Então, em seu modelo de votos, você precisará atualizar o $belongsTo
Definição ligeiramente:
class Votes extends AppModel
{
var $belongsTo = array(
'Contestant' => array( 'counterCache' => true )
);
}
Agora, sempre que um registro de voto é salvo, o vote_count
O campo do concorrente dos pais será atualizado. Agora você pode simplesmente resolver Contestant.vote_count
Como você faria em qualquer outro campo dos competidores:
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...
}