dbourdette / fun-reco

0 stars 0 forks source link

Modèle de données pour les profils et les actions #16

Closed dbourdette closed 12 years ago

dbourdette commented 12 years ago

A la suite de l'installation du plugin mongo (#15) nous allons définir le modèle de données sauvées en base.

Actuellement, les classes Action, Object, Friend et Profile sont les classes publiques de notre API. Elles servent aux contrôleurs, à la facade et serviront pour l'API REST.

En prévision de l'API REST, il n'y a pas de lien entre un profil et ses amis dans ce modèle. De même, au travers de la facade, je mets soit à jour le profil, soit ses amis. C'est assez cohérent mais ce lien entre les profils et les amis doit exister en base.

Nous allons donc définir un nouveau modèle de données juste pour la persistance.

A faire :

Mongodb étant une base de données orientée document, la définition du modèle en base de données est en fait plus simple et plus souple mais, il n'y a pas de relation entre les entités (foreign key).

dbourdette commented 12 years ago

Les test passent avec

grails test-app integration:

Voici quelques corrections apportées :

Voici ce qui risque de poser problème par la suite :

aprestaux commented 12 years ago

Je pensais qu'a terme, les objets dans le src/groovy (package com.github.funreco) seraient déplacés dans le legacy, ce n'était pas le plan ? Si ce n'est pas le cas, je pense qu'il faudrait effectivement changer le nom des objets du domain pour éviter la confusion. Je ne comprend pas ce que vous voulez dire par "les tests unitaires ne nettoient pas la base" Les tests unitaires utilisent la même base que l'application mais puisque que les tests d'intégration sont designés pour supprimer les objets crées lors du test à la fin de celui-ci je pensais que ça ne posait pas de problème. Enfin concernant la liste des amis, dans le modèle actuel les ids stockées sont des ObjectsIds de Profile, qui permettent donc d'accéder aux noms ensuite. Nous pensions qu'il était peut-être trop redondant de stocker la facebookId et le nom à chaque fois, qu'en pensez-vous ?

dbourdette commented 12 years ago

Tout ce qui doit aller dans legacy y est déjà. La facade en place permet justement de passer d'une implémentation du moteur a une autre sans modifier les controleurs / vues et les services REST à venir. Les objets qui sont publics au travers de la Facade sont donc aussi a conserver.

Pour les tests unitaires, généralement, on rétablit la base dans un état canonique (vide ?) au début de chaque test. Cela se faire dans une méthode spéciale. Avec JUnit 4, il suffit d'annoter une méthode @Before

A mon sens, quand on veut surfer et développer l'application, on est en dev mode (on peut bootstraper la base). Pour les tests, on est en test mode : la base est remise a zéro (ou données de références pour les tests) à chaque test En mode prod, on jette rien. -> Les environnements dans grails

Du point de vue des tests, je dirais :

Pour bien faire, il faudrait donc bien remplir le DataSource.groovy. Pour la base de test on peut prendre exactement les mêmes paramètre et juste changer le nom de la base.

Enfin pour le modèle, je n'avais pas compris cela en voyant le nom de l’attribut. Dans ce cas, je vous conseille de le nommer friendIds. Il est de toutes façons déconseillé de nommer un attributs en fonction de son type. Cela revient a dire que l'email pourrait être emailString pas exemple. Pour les collections, si vous changer son type, cela aurait un impact assez grand alors que par exemple vous êtes passés d'une List à un Set.

aprestaux commented 12 years ago

Es-ce que cela ne risque pas de poser un problème par rapport a la façade (dont les fontions rendent par exemple des List) de changer le nom des objets utilisés par notre implémentation ?

dbourdette commented 12 years ago

Je ne comprends pas bien la question. Toutes les implémentations de la Facade renvoient les mêmes types d'objets défini dans l'interface. Chaque implémentation se charge de convertir les données afin de les persister comme bon lui semble.

aprestaux commented 12 years ago

Mais les objets ne sont pas définis dans la Facade, actuellement au vu du package de la RecommandationFacade, les objets à renvoyer correspondent au objets définis dans le src/groovy Même si les implémentations changent de package afin de gérer la persistence de manière indépendante, est-ce qu'il n'est pas indispensable que le nom des objets corresponde à celui de l'interface ?

aprestaux commented 12 years ago

J'ai essayé de configurer une base pour les tests, mais puisque Grails vide tout seul la base a la fin des tests j'ai du mal à savoir si ma configuration fonctionne : je ne vois pas apparaitre de DB qui s'appelle fun-reco-test dans mon serveur MongoDB

dbourdette commented 12 years ago

Les objets qui sont dans les sigantures de la facade sont dans le même package : com.github.funreco

Vous pouvez regarder comment LegacyRecommendationFacade fait pour faire les traduction com.github.funreco <-> com.github.funreco.legacy.domain;

dbourdette commented 12 years ago

Même si grails vidait la base (ce qu'il ne fait pas je pense) elle serait encore présente à la fin (mais vide).

Donc c'est sans doute que les objets ne vont pas en base.

Pouvez vous tester un save(flush: true) ?

aprestaux commented 12 years ago

Avec un save(flush: true), on voit effectivement que les objets ne vont pas dans la bonne base, ils sont sauvés dans fun-reco et non dans fun-reco-test. Je vais essayer de regarder ça maintenant que je sais comment laisser les objets dans la base lors des tests

dbourdette commented 12 years ago

Du coup un clean avec un @Before risque d'être nécessaire.

Le flush est en lien avec GORM. Cela n'a aucun sens pour une base mongodb mais est une optimisation forte d'hibernate pour les base de données relationnelles.

Une possibilité est donc de surcharger save() dans les objet du domain afin que cette méthode appelle save(flush: true) par défaut. Les tests unitaires n'ont pas vraiment a gérer cela.

dbourdette commented 12 years ago

Pour les bases, je ne suis pas du tout sur de quelle base (via l'environnement) correspond a quels types de tests avec grails.

aprestaux commented 12 years ago

La dernière version commitée fonctionne (j'avais mal écrit le DataSource.groovy en fait). Avec le save(flush: true) dans les tests, on voit bien les objets de tests en base fun-reco-test. Cette base est vidée à chaque nouvelle instanciation des tests (dans le Bootstrap.groovy) Le flush: true n'est pas nécessaire pour bien sauvegarder les objets lorsque que nous ne sommes pas dans un test (j'avais testé avec les objets Persistence et ça marchait bien), je pense que ce flush empeche juste Grails de vider sa base de test automatiquement à la fin des tests comme il devait le faire avant, j'avais lu ça quelque part c'est pour ça que j'avais mis les tests de persistance dans /integration, mais impossible de retrouver où.

dbourdette commented 12 years ago

le flush: true impose de pousser immédiatement les données vers la base.

Dans le cas d'une requête http, l'ensemble des push se font à la fin du traitement de la requête.

C'est une mécanique dérivé du pattern Unit of work. C'est une optimisation que permet hibernate afin d'optimiser les appels à la base.

Enfin, je continue de penser que grails ne vide pas la base automatiquement entre les tests. Il serait très délicat de le faire à cause des contraintes d'intégrité des bases relationnelles (foreign keys). Si on ne fait pas de flush manuel, le données reste dans la Session hibernate, ce qui peut faire croire qu'elle sont en base. Ce qui peut être suffisant pour certains tests, mais qui ne me semble pas suffisant pour des tests de persistance.

aprestaux commented 12 years ago

Je pense que j'ai du confondre entre des objets gardés en session et abandonnés en fin de test et le fait de vider la base. Je comprends mieux maintenant, merci pour les précisions.