Symfony et la base de données

Mon projet avance. J'utilise maintenant une base de données avec tout ce que fourni Symfony.

Encore une fois, je ne fais pas un didacticiel. Je vais juste dire rapidement ce que j'ai dû faire et donner mes impressions.

Configurer sa base de données

En un mot: fastoche !

En lisant la doc 08-Inside-the-Model-Layer.txt, ça se fait tout seul.

Il y a un fichier de configuration pour la connexion à la base de données, pour l'instant, rien de spécial. Mais il y a surtout le schema de la base écrit en YAML, et ça c'est sympa. Voilà à quoi ressemble le mien pour l'instant:

propel:
  law:
    _attributes: { phpName: Law }
    id:
    category_id:  { type: integer, foreignTable: category, foreignReference: id, onDelete: cascade }
    message:      longvarchar
    created_at:
    updated_at:
    enabled:      boolean
    
  category:
    _attributes: { phpName: Category }
    id:
    label:        varchar(255)
    created_at:
 

Vous remarquerez que parfois, je ne met pas le type du champ. C'est parce qu'il y a une convention de nommage qui permet d'affecter automatiquement des types. Comme id qui est un INTEGER, primary key et auto-increment.

Création des classes

Ce que j'aime particulièrement, c'est la création des classes automatiquement avec les getter et les setter. A chaque fois qu'on modifie le schema, on peut relancer la génération des fonctions de base. Ca fait gagner un temps fou ! J'ai donc déjà les méthodes:

  • Law->getId()
  • Law->getMessage()
  • Law->getCategory() (et là, ce qui est cool, c'est qu'il me renvoit un object de type Category, de l'autre table)
  • Category->getId()
  • Category->getLabel()
  • Category->delete() (si j'efface une catégorie, ça va effacer toutes les lois qui étaient dedans)
  • etc.

De plus, il y a aussi des classes avec des méthodes statiques pour retrouver des enregistrements:

  • LawPeer::retrieveByPk($id)
  • LawPeer::doSelect($criteria)
  • CategoryPeer::doCount()
  • etc.

Génération de l'admin

Et pour couronner le tout, on peut même générer un site admin pour gérer ses données. Tout ça en ligne de commande. Ca se passe dans la doc 14-Generators.txt.

La seule chose que le générateur ne fait pas, c'est le routing. Voilà ce que j'ai dû écrire moi même:

law_list:
  url:   /law
  param: { module: law, action: list }
 
law_show:
  url:   /law/:id.html
  param: { module: law, action: show }
 
law_create:
  url:   /law/create
  param: { module: law, action: create }
 
law_edit:
  url:   /law/edit/:id
  param: { module: law, action: edit }
  
law_update:
  url:   /law/update
  param: { module: law, action: update }
 
law_delete:
  url:   /law/delete/:id
  param: { module: law, action: delete }
  
 
category_list:
  url:   /category
  param: { module: category, action: list }
 
category_show:
  url:   /category/:id.html
  param: { module: category, action: show }
 
category_create:
  url:   /category/create
  param: { module: category, action: create }
 
category_update:
  url:   /category/update
  param: { module: category, action: update }
 
category_edit:
  url:   /category/edit/:id
  param: { module: category, action: edit }
 
category_delete:
  url:   /category/delete/:id
  param: { module: category, action: delete }
 

Et dans l'admin, quand je crée/edite une loi, je peux choisir la catégorie dans une liste déroulante. Symfony m'a retrouvé toutes les catégories existantes. J'arrive même pas à imaginer le temps que ça m'aurait pris pour faire ça.

Conclusion

Ca déchire !

J'continue le projet ...

Commentaires

1. Le vendredi, janvier 25 2008, 23:13 par Neovov

Au début c'est pas mal, mais dans un gros projet on déchante vite.

Il y a des fichiers partout, la configuration à gérer (avec une doc très limitée), le routing (un peu limité), et il suffit d'y ajouter l'i18n pour se retrouver avec un truc très lourd.

Si en plus on développe sans avoir fait la BDD on est obligé d'ouvrir les classes générées automatiquement, quand il y a 3-4 champs ça va, mais ça devient vite plus complexe (et ça juste pour trouver la bonne méthode pour récupérer la donnée que l'on veut).

Un exemple, avec ta classe Law on obtient :
model/Law.php
model/Law_i18n.php
model/Law_i18nPeer.php
model/LawPeer.php
model/om/BaseLaw.php
model/om/BaseLaw_i18n.php
model/om/BaseLaw_i18nPeer.php
model/om/BaseLawPeer.php

2. Le vendredi, janvier 25 2008, 23:44 par neolao

Ouais ca va, j'ai l'habitude des nombreux fichiers. De toute façon, j'aurai écrit moi même ces classes et méthodes, sauf les Base qui servent à pas écraser ce que j'fais.

Par contre, j'ai pas pu faire des choses avec le routing, mais je n'ai pas vraiment exploré.

3. Le dimanche, janvier 27 2008, 20:51 par Gregoire

Je dirai que c'est plutot le contraire. J'utilise énormément symfony, et c'est plutot au départ que j'ai déchanté. Le fait qu'il y ait beaucoup de fichiers (avec une architecture en cascade) surprend lorsqu'on démarre. Mais une fois accoutumé, c'est tres pratique et on retrouve tout de suite le fichier dont on a besoin, meme parmis plusieurs centaines.

Petite remarque concernant ton routing :
le fait d'écrire
category_create:
url: /category/create
param: { module: category, action: create }

ne sert a rien car tu obtiens la meme adresse sans le routing. Par contre c'est utile par exemple si tu ecris :
category_create:
url: /nouvelle-categorie
param: { module: category, action: create }

Good luck !
Greg

4. Le dimanche, janvier 27 2008, 21:56 par neolao

ouais, c'est vrai

Moi j'ai viré le /:module/:action/*

J'ai préféré avoir toutes les urls que j'utilise

C'est comme pour _attributes: { phpName: Law } qui ne sert pas. Il y a un camelcasation à partir du nom de la table

5. Le jeudi, janvier 31 2008, 10:28 par Furax

Bonjour,
le routing qu'il écrit est utile cela permet permet d'utiliser le "routing inverse" dans les template à l'aide de @category_create.

6. Le samedi, mai 31 2008, 11:00 par fils rss

merci pour ce billet, c'est toujours intéresssant de vous lire. Je me demandais cependant pourquoi cettye parenthèse : si j'efface une categorie, ca va effacer toutes les lois qui etaient dedansb ? :)