J'ai été occupé avec le framework cakePHP pendant quelques mois maintenant et je l'aime vraiment. En ce moment je travaille sur un tout nouveau projet et il fait le travail comme il se doit (je pense ...) mais je me sens mal à l'aise avec un code que j'ai écrit. En fait, je devrais optimiser ma requête de conditions de pagination afin d'obtenir immédiatement les bons résultats (maintenant je manipule le jeu de résultats par une série d'appels de méthode Set ::Requête de recherche complexe pour la relation hasMany dans cakePHP 1.3
Je vais esquisser les aspects pertinents de l'application. J'ai un modèle 'Site' qui a une relation hasMany avec le modèle 'SiteMeta' Cette dernière table ressemble à ceci: id, id_site, clé, valeur, créé
Dans ce dernier modèle, j'enregistre plusieurs valeurs du Le nom de la clé que je veux stocker (par exemple, alexarank, google pagerank, ...), et bien sûr aussi la valeur.A un intervalle donné, je laisse mon application mettre à jour cette base de données afin que je puisse suivre l'évolution de ces valeurs
Maintenant, mon problème est le suivant.
Sur la page d'aperçu des différents sites Web (controller => Sites, action => index) Je souhaite afficher le pagerank ACTUEL du site. J'ai donc besoin d'un enregistrement SiteMeta exact où le champ 'créé' est le plus haut et la valeur 'clé' devrait correspondre au mot 'pagerank'. J'ai essayé plusieurs choses que j'ai lues sur le net mais je n'ai obtenu aucun d'entre eux (containable, bindmodel, etc.). Je fais probablement quelque chose de mal.
En ce moment j'obtenir des résultats comme celui-ci quand je fais un $ this-> paginez
Array
(
[0] => Array
(
[Site] => Array
(
[id] => 1
[parent_id] => 0
[title] => test
[url] => http://www.test.com
[slug] => www_test_com
[keywords] => cpc,seo
[language_id] => 1
)
[SiteMeta] => Array
(
[0] => Array
(
[id] => 1
[site_id] => 1
[key] => pagerank
[value] => 5
[created] => 2010-08-03 00:00:00
)
[1] => Array
(
[id] => 2
[site_id] => 1
[key] => pagerank
[value] => 2
[created] => 2010-08-17 00:00:00
)
[2] => Array
(
[id] => 5
[site_id] => 1
[key] => alexa
[value] => 1900000
[created] => 2010-08-10 17:39:06
)
)
)
Pour obtenir le pagerank je viens de boucle à travers tous les sites et de manipuler ce tableau que je reçois. Ensuite, je filtre les résultats avec Set :: extract. Mais cela ne se sent pas tout à fait raison :)
$sitesToCheck = $this->paginate($this->_searchConditions($this->params));
foreach($sitesToCheck as $site) {
$pagerank = $this->_getPageRank($site['Site']);
$alexa = $this->_getAlexa($site['Site']);
$site['Site']['pagerank'] = $pagerank;
$sites[] = $site;
}
if (isset($this->params['named']['gpr']) && $this->params['named']['gpr']) {
$rank = explode('-', $this->params['named']['gpr']);
$min = $rank[0];$max = $rank[1];
$sites = Set::extract('/Site[pagerank<=' . $max . '][pagerank>=' . $min .']', $sites);
}
$this->set(compact('sites', 'direction'));
Pourriez-vous m'aider s'il vous plaît à réfléchir à une solution pour cela? Merci d'avance.
Merci pour les contributions. J'ai essayé ces options (aussi quelque chose avec bindmodel mais ne fonctionne pas aussi) mais je n'arrive toujours pas à faire fonctionner ça comme il se doit. Si je décris cette
$this->paginate = array(
'joins'=> array(
array(
'table'=>'site_metas',
'alias'=>'SiteMeta',
'type' =>'inner',
'conditions' =>array('Site.id = SiteMeta.site_id')
)
),
);
-je obtenir des résultats en double J'ai un site avec 3 enregistrements SiteMeta différents et un site avec 2 dossier différent. La méthode paginate me renvoie 5 enregistrements au total. Il ya probablement une solution facile pour cela, mais je ne peux pas le comprendre :)
J'ai aussi essayé d'écrire une requête sql moi-même, mais il semble que je ne puisse pas utiliser la magie de la pagination dans ce cas. La requête que j'aimerais imiter avec les options et les conditions de pagination est la suivante. La requête retourne exactement comme je voudrais l'obtenir.
$sites = $this->Site->query('SELECT * FROM sites Site, site_metas SiteMeta WHERE SiteMeta.id = (select SiteMeta.id from site_metas SiteMeta WHERE Site.id = SiteMeta.site_id AND SiteMeta.key = \'pagerank\' order by created desc limit 0,1)');
Alors, quel tableau voulez-vous avoir en conséquence au lieu de votre paginate? Ou quelle requête SQL voulez-vous produire? – bancer
merci pour la réponse rapide. Je pensais à un tableau avec un seul élément sur l'index SiteMeta au lieu de 3 dans l'exemple. J'aimerais pouvoir appeler simplement la valeur de cet enregistrement, donc je n'aurais pas à boucler le tableau et à changer le tableau moi-même en ajoutant des indexés comme pagerank ou alexa. Est-ce que cela pourrait être accompli? Une suggestion pour une solution meilleure et plus propre est également ok hehe :) – Laurent