Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Hello,
Je débute avec ce framework et pour le moment j'avoue que le mapping Db me pose soucis.
J'ai 2 tables 'users' (user_id, user_name, user_firstname) et 'sections' (section_id, user_id, section_title, section_controller) liées par la foreign key sections.user_id
Je souhaite executer la requête suivante:
SELECT section_title, CONCAT(user_firstname, user_name) FROM sections AS s INNER JOIN users AS u ON s.user_id = u.user_id WHERE section_controller = 'index';
Par conséquent, j'ai le model 'Sections' suivant :
class Sections extends Zend_Db_Table { protected $_name = "sections"; protected $_primary = "section_id"; public function getSection($controller = 'index', $lang = 'en') { $select = $this->select(); $select->from(array('s' => $this->_name), array('section_title', 'section_date')); $select->join(array('u' => 'users'), 's.user_id = u.user_id', array('user_name', 'user_firstname')); $select->where('s.section_controller = ?', $controller); return ($this->fetchAll($select)); } }
J'obtiens l'erreur suivante:
Warning: Select query cannot join with another table in D:\www\mydirco\src\library\Zend\Db\Table\Select.php on line 191
Plus généralement, comment faites-vous pour effectuer vos jointures sur des tables? Comme ça ou y a mieux? Parce que j'ai vu bcp de méthodes différentes sur Internet et j'ai fini par faire pas mal de mélanges. Bref, je suis un peu perdu. Et je suppose que cette méthode fonctionne aussi pr n tables soit n jointures?
Merci d'avance pour vos lumières.
Dernière modification par Echo (13-04-2008 17:45:48)
Hors ligne
il faut que tu renseignes les attributs :
protected $_dependentTables : contient les tables dépendant de la table courante
protected $_referenceMap : contient le nom des colonnes pour les dépendances.
et cela pour chacune de tes tables.
Conseil : fais comme moi, construis toi un générateur de code qui à partir de la base de données, bien commentée et correcte au niveau des clés, va construire les fichiers classes nécessaires (table avec les noms des champs etc..., les row, les rowset...plus tout ce que tu as besoin pour travailler). Moi, j'ai fait un MDA like : mon générateur met à jour toutes mes classes "métier" liées à la base de données, sans pour autant supprimer le code que j'ai manuellement écrit pour parfaire mes classes, notamment des méthodes supplémentaires.
C'est long et fastidieux mais une fois fini, quel gain de temps!!!A chaque modif de base, je régénère toutes mes classes (il y en a une dizaine par table et j'ai bien une soixantaine de tables!!!). De plus, toutes mes classes sont "propres" : toutes documentées de la même façon!! Les dates de mise à jour de classes sont automatiques, ainsi que le "type" des attributs de ma classe (en fait le commentaire indique le type de la colonne avec un commentaire récupéré depuis chaque colonne de chaque table).
De plus, cet automate vérifie que mes tables sont conformes à mon standard (par exemple, que chaque table possède bien un colonne nommée nom_de_la_table_id et de type integer).
Yoong
Hors ligne
kiminox a écrit:
il faut que tu renseignes les attributs :
protected $_dependentTables : contient les tables dépendant de la table courante
protected $_referenceMap : contient le nom des colonnes pour les dépendances.
et cela pour chacune de tes tables.
J'ai en effet lu ça dans le tutoriel de Julien PAULI sur developpez.com mais pas encore eu le temps de tester car ...
kiminox a écrit:
Conseil : fais comme moi, construis toi un générateur de code qui à partir de la base de données, bien commentée et correcte au niveau des clés, va construire les fichiers classes nécessaires (table avec les noms des champs etc..., les row, les rowset...plus tout ce que tu as besoin pour travailler)
J'ai eu la même idée que toi
J'ai déjà commencé vite fait le boulot...
Hors ligne
ça serait peut être intéressant de publier votre code.
Qu'en pensez vous ?
Hors ligne
golivier a écrit:
ça serait peut être intéressant de publier votre code.
Je voulais le demander à kiminox, seulement je suppose qu'il m'aurait déjà proposé son propre code...
[Hs]JE viens de remarquer que tu es toi aussi un ventrachou golivier! [/Hs]
[Edit]
Bon, j'ai fini et testé mon générateur de classes Zend_Db_Table_Abstract : ça fonctionne bien, que ce soit en création qu'en update après modifications de la base de données et avec conservation des méthodes implémentées.
Parcontre, avec un describeTable, on a pas la possibilité de savoir si le champs est une foreign key... Etant débutant sous Zend Framework, n'étant pas expert PHP et disposant de peu de temps pr coder, il a fallu bidouiller un peu.
Dans mon cas, ce fut assez simple grâce à la règle de nommage que je me suis imposé:
- noms des tables au singulier, en lettres uniquement, la première en majuscule (par exemple Category)
- noms des champs préfixés par le nom de la table et d'un underscore, tout en minuscule (par exemple category_name)
- tous les identifiants (primary et foreign) conservent leurs noms : de cette manière, avec une regexp, je peux de suite savoir si il s'agit d'une foreign key et de quelle table vient cet id;
- tous les nommages sont réalisés en anglais (conservation du sens, sans accent).
Ces règles me semblent élémentaires ds le développement de bases de données car de cette manière la lecture devient plus aisée (on identifie d'un seul coup d'oeil les foreign key et leur table de provenance) et chaque champs est unique.
Bref, revenons-en à nos moutons... Si votre base de données ne respecte pas ces règles : libre à vous d'adapter le code et votre base de données! Sinon, vous pouvez d'ores et déjà stopper votre lecture ici!
Il me reste juste à :
- lister le répertoir 'models' contenant les fameuses classes afin de supprimer celles qui pourraient disparaitre suite à modification du MCD ;
- réduire les portions de code qui se répètent ;
- commenter un peu.
Les fichiers, qui seront mis à jour au fur et à mesure des remarques/conseils/critiques, sont téléchargeables sur mon site Web
Le zip est constitué de 3 fichiers à placer dans :
application/models/Database.php
application/controllers/AdminController.php
application/views/scripts/admin/database.phtml
[/Edit]
Dernière modification par Echo (14-04-2008 08:53:43)
Hors ligne
kiminox a écrit:
il faut que tu renseignes les attributs :
protected $_dependentTables : contient les tables dépendant de la table courante
protected $_referenceMap : contient le nom des colonnes pour les dépendances.
Bon ça y est c'est résolu... En effet il faut ces deux variables de renseignées mais ce n'est pas suffisant... Après un peu de lecture du man du Zend Framework, j'ai trouvé une solution : setIntegrityCheck(false)
public function indexAction() { $cities = new City(); $select = $cities->select(); $select->setIntegrityCheck(false) ->from('City')
Dernière modification par Echo (13-04-2008 17:45:28)
Hors ligne
Un grand merci à posterieuri : ce fameux setIntegrityCheck() a également réglé mon problème !!!
Hors ligne
Et le mien tks
Hors ligne
Tout le monde se heurte à cette obscure méthode setIntegrityCheck dès la première jointure, vivement qu'elle soit virée :\
http://framework.zend.com/manual/fr/zend.db.table.html
L'objet Zend_Db_Table_Select est destiné à selectionner des données sur une table précise. Des jointures peuvent être faites, mais il n'est pas possible de sélectionner des colonnes ne faisant pas partie de la table sous jascente. Cependant, ceci aurait pu être utile dans certains cas, et l'objet Zend_Db_Table_Select possède une clause spéciale dévérrouillant cette limitation. Passez la valeur false à sa méthode setIntegrityCheck. Il est alors possible de sélectionner des colonnes hors table. Attention toutefois, l'objet row/rowset résultant sera vérrouillé. Impossible d'y appeler save(), delete() ou même d'affecter une valeur à certains de ses champs. Une exception sera systématiquement levée.
Dernière modification par fte (11-07-2008 09:47:26)
Hors ligne