Paginierung mit hasMany Verein CakePHP
-
22-09-2019 - |
Frage
Ich habe zwei Tabellen:
Kandidat und Abstimmungen Kandidat hasMany Stimmen
Ich habe versucht, eine Zählung (Vote.id) als Stimmen zu tun, damit ich es auf dem Platz kann Cord-Set und Paginieren sie nur, aber ich habe keine Ahnung, wo es zu platzieren. Ich habe es auf den Feldern Array aber es gab mir die Gesamtzahl der Stimmen unabhängig von dem Kandidaten sie gehören.
Die Stimmen werden zusammen in der Kandidaten-Cord verknüpft so, was ich tat, war auf meiner Ansicht ich eine Zählung tat ($ Kandidat [Bewerten]), aber das kann nicht sein Paginierung und mein Kunde will in der Lage sein, die Kandidaten zu sortieren nach Stimmen.
Gibt es eine Weise, die ich so etwas wie dies auf meiner Ansicht nach tun können:
sort ( 'Stimmen', 'count (Stimme)'); ?>
Oder muss ich eine Abfrage erstellen, die hat eine Zählung für alle Stimmen wo Contestant.id = Votes.contestant_id?
Controller Kandidat:
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',
$ Bedingungen)); }
Lösung 2
Da CakePHP nicht Gruppe unterstützt durch in contain Verhalten habe ich versucht, einen anderen Ansatz. Erstellen Sie die Paginieren var für die Abstimmung Modell statt (All dies in dem Teilnehmer-Controller durchgeführt wird):
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'
)
)
);
Und jetzt in meinem Controller kann ich die folgende:
function index() {
$page = 'Contestants';
$this->set('page', $page);
$conditions ["Contestant.active"] = 1;
$this->set('contestants', $this->paginate($this->Contestant->Vote,$conditions));
}
Nun werden die Teilnehmer durch ihre Gesamt Abstimmung Tally bestellt, obwohl ich immer noch nicht, wie die Contestant_votes als paginator Variable zu setzen, da im Datensatz ist in einem Array von ihm selbst ist und nicht in einem der Modell-Arrays verwendet paginieren.
Danke Matt Huggins Ihr Ansatz war derjenige, der mich zu dieser Lösung geführt.
Andere Tipps
Überprüfen Sie deceze Antwort auf diese Frage aus: CakePHP mathematisch-Berechnungsfeld
Im Grunde wollen Sie so etwas wie dies zu tun, ich bin zu raten:
'contain' => array(
'Vote' => array(
'fields' => array('SUM(Vote.id) AS Contestant__votes'),
'group' => array('Vote.contestant_id'),
)
)
Zusatz: Möchten Sie auch von Stimmen (Stimmen insgesamt) auf- oder absteigend sortiert werden? Wenn ja, man kann es nicht einfach tun, indem Sie die Standard-Paginierung Methode von CakePHP.
, dass Sie ein wenig zwicken müssen. Hier sind die Details zu diesem Trick: CakePHP Erweiterte Paginierung - sortiert nach abgeleitetem Feld
Hope würden Sie finden es hilfreich.
Danke Adnan
Für die spezielle Beziehung, die Sie definieren, werden Ihre Bedürfnisse gut bedient von Gegen Caching .
Sie müssen ein neues Feld in Ihrer contestants
Tabelle definieren: vote_count
. Dann in Ihrem Stimmen Modell, werden Sie die $belongsTo
Definition aktualisieren müssen leicht:
class Votes extends AppModel
{
var $belongsTo = array(
'Contestant' => array( 'counterCache' => true )
);
}
Nun jederzeit eine Abstimmung Datensatz gespeichert wird, wird das vote_count
Feld der Mutter Kandidaten aktualisiert werden. Jetzt können Sie einfach sortiert nach Contestant.vote_count
wie jeder anderen Kandidaten Feld:
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...
}