- 1
[Opened] Table de liaison
Posted by dantahoua on 01/20/2010 21:14
Bonjour, encore moi... Pour l'instant je me débrouille très bien tant qu'il n'y a pas de table de liaison, ou des liaisons simple. Mais là je suis perdu dés qu'on introduit une table de liaison. J'ai regardé dans la forge si je trouvais des exemple mais je n'en ai pas vu (peut être avec jTags mais il semble que cela passe par un Dao...). Toujours dans un soucis de bien faire, j'essaye donc de gérer des news, chacune pouvant faire partie de plusieurs catégories. Une catégories peut elle aussi être liée à plusieurs news. Donc on a besoin d'une table de liaison. Après plusieurs recherches sur le forum, j'ai vu que gérer ça avec le dao, c'est pas simple, voir pas possible. Donc il semblerait que ma gestion va se faire "à l'ancienne" dans une classe avec des requêtes sql. Si je comprend bien, je ne pourrais pas utiliser un formulaire CRUD puisque lui se base sur jDao? Ma strucure (simplifiée):
- Table news (id, title, content,date)
- Table categories(id, title)
- Table lnk_news_categories(fk_id_news, fk_id_categories)
Comme je suis en Inodb, pour l'effacement j'utilise un Cascade, ce qui simplifie le code php. Mes questions:
- La classe qui va gérer mes updates et créations de news (donc lier à une catégorie), ou mon listage de news va aller dans news/classes ?
- Comment vais-je lier un formulaire à cette classe?
- Puis-je toujours utiliser mes formulaires avec jControllerDaoCrud ?
- Pourrais-je avoir un petit exemple, pas besoin de trop pousser?
Je posterai ma solution une fois le produit fini, ça pourra être utile pour d'autre développeur à débuter avec Jelix. Ce framework est génial!
[Opened] Re: Table de liaison
Posted by foxmask on 01/21/2010 07:04
Bonjour,
la question est récurrente ces derniers temps, je ne saurai que vous conseiller de faire un petit tour sur cette longue discussion ;)
Architecture : faut-il utiliser les DAO dans les contrôleurs
cdt.
@GitHub - Forum HaveFnuBB! powered by Jelix - Le Booster Jelix !
[Opened] Re: Table de liaison
Posted by laurentj on 01/21/2010 11:44
Aucun rapport avec le crud. Le controlleur crud ne t'empeche pas d'utiliser une table de liaison.
Dans ton formulaire, tu va logiquement utiliser une liste de checkbox ou une listbox avec selection multiple. Donc dans ton jforms, tu utiliseras un <checkboxes> ou <listbox multiple="true">, dont la source de donnée est ta table de categories. Et pour preselectionner les items de la listbox ou ta liste de chackbox, tu appelera la méthode initControlFromDao() de ton objet jforms, avant affichage. Et pour sauver les selections de ces contrôles, tu appeleras saveControlToDao. Bien sûr, il te faut un dao pour ta table lnk_news_categories. voir la doc de réference de ces méthodes, et la doc sur jforms
Bref, tout est prévu.
[Opened] Re: Table de liaison
Posted by dantahoua on 01/22/2010 13:30
Reste un petit problème, y'a qqchose que j'ai pas du comprendre. J'arrive à faire des update en faisant:
protected function _editUpdate($form, $resp, $tpl){ $form->initControlFromDao("categories", "news~newscat"); } protected function _beforeSaveUpdate($form, $form_daorec, $id){ $form->saveControlToDao('categories', 'news~newscat'); }
Là ça fonctione super, ça rajoute ou enlève les liasons comme il faut.
Par contre je n'arrive pas à créé un nouvel enregistrement au complet. Il me semble pourant qu'il faut utiliser
protected function _afterCreate($form, $id, $resp){ $form->saveControlToDao('categories', 'news~newscat'); }
mais ça me retourne
Impossible d'utiliser le control "categories" avec la dao car le formulaire news~newsform n'a pas d'id
La news est bien insérée dans la table news mais pas la liaison, c'est comme si il ne retournait pas l'insert id...
[Opened] Re: Table de liaison
Posted by laurentj on 01/22/2010 15:29
En effet, l'id du formulaire reste inchangé (normal) malgré l'enregistrement. Mais par défaut, saveControlToDao utilise l'id du formulaire comme id pour l'enregistrement. Ce qui, dans le cas d'une création, ne va pas. Il suffit alors de passer le bon id à la méthode, que tu reçoit en paramètre ($id)
$form->saveControlToDao('categories', 'news~newscat', $id);
[Opened] Re: Table de liaison
Posted by dantahoua on 01/22/2010 15:40
Super, merci! Ça fonctionne! Me reste plus qu'à trouver comment afficher côté client, genre "Toutes les news de la catégories 'informatique'".
[Opened] Re: Table de liaison
Posted by dantahoua on 01/22/2010 20:47
Pour le côté client, apparemment je ne peux utiliser directement les Dao simplement à partir du moment où il y a table de liaison, Alors voilà comment j'ai fait:
- classes news dans mon module news
class news { public function getNewsByCategories($idCat = null) { $cnx = jDb::getConnection(); $rs = $cnx->query('SELECT title,content,date_start FROM news, lnk_categories_news lnk WHERE news.id = lnk.fk_news_id AND lnk.fk_categories_id = '.$idCat); return $rs; } }
- dans mon controleur j'ai une nouvelle action test
function test() { $rep = $this->getResponse('html'); $objNews = jClasses::getService("news~news"); if($this->param('idcat')){ $idCat = $this->param('idcat'); $liste = $objNews->getNewsByCategories($idCat); $tpl = new jTpl(); $tpl->assign('liste', $liste); $rep->body->assign('MAIN', $tpl->fetch('listenews')); } return $rep; }
Cette méthode est elle la bonne? Au moins je ne fait qu'une seule requête à ma base de données. Par contre comment faire un échappe sur le param pour éviter l'injection sql? Quand je fait $cnx->prepare , ça me dit que ce n'est pas supporté par MySql...
[Opened] Re: Table de liaison
Posted by laurentj on 01/23/2010 00:15
Par contre comment faire un échappe sur le param pour éviter l'injection sql?
euh...
$cnx->query('SELECT title,...' . intval($idCat));
faut pas chercher midi à quatorze heure..
pour les chaines : $cnx->quote($valeur);
[Opened] Re: Table de liaison
Posted by dantahoua on 01/26/2010 15:58
Merci foxmark, j'avais effectivement regardé ces deux classes, je n'étais pas sur, mais maintenant je vais mieux les regarder. Si je me rappel bien par contre cela engendre plus d'une requête à la BD, ce qui n'est pas grave, mais j'aime bien essayer d'avoir le minimum de connexion au serveur MySQL et laisser Php travailler un peu plus, les ressources php sont souvent peu utiliser. Nous avons eu l'exemple ici à Québec avec un site qui avait plus de 40000 connexion journée, et le problème venait toujours du nombre trop grand de connexion à MySql. C'est sur le site n'était pas super bien fait et il n'y avait pas de cache!
[Opened] Re: Table de liaison
Posted by foxmask on 01/26/2010 21:50
Bonsoir,
une technique que m'a fourni Laurent consiste à mettre dans un array le record voulu à chaque "get" et de le tester. Ainsi gain d'économie sur les requêtes de la base. Donc par la suite, dans l'application on ne fait plus de $dao->get($id) mais jClasses::getServices('foo~bar')->getThat($id); par exemple où getThat est la méthode permettant de récupérer Un record par la primary key du Dao de son choix. Grooso modo c'est le mécanisme que j'ai dû mettre en place dans la classes sus mentionnée.
Bonne soirée.
Cdt.
@GitHub - Forum HaveFnuBB! powered by Jelix - Le Booster Jelix !
- 1