Hi there !
Mon message n’est pas vraiment une question, c’est juste une petite
synthese
de reflexions sur le systeme des associations / validation / callbacks
dans
RoR qui peut-etre eviterons a certains de passer des heures sur de
vaines
recherches (argh je deviens aigri !).
J’espere que vous comprendrez mes exemples
- Les callbacks:
Alors ce que j’ai decouvert est assez surprenant. Prenons un exemple
simple,
nous avons 2 models differents:
- model Content qui possede 2 images de type Image
class Content < ActiveRecord::Base
has_one :banner, :class_name => ‘Image’
has_one :vignette, :class_name => ‘Image’
end
- model Image qui possede un callback (before_save par exemple) qui pour
une
raison X entraine un return false (donc casse la “chain”, cf doc api).
Hypotheses pour ce modele: la sauvegarde de :banner entraine un return
false
(cf ci-dessus) MAIS la sauvegarde vignette est OK quant a elle.
Essayons de sauver en base une instance de Content
==> resultats: banner non sauvegardee (car chaine cassee) DE MEME QUE
vignette (rien ne sera “processe” sur vignette, aucune validation, aucun
callback, nada). Excellent non ? Alors que banner et vignette sont 2
objets
differents en memoire !!!
Si on inverse l’ordre des associations dans Content, c’est l’inverse
(normal).
- Sauvegarde des associations
Genial avec RoR, les associations sont sauvegardees automatiquement que
cela
soit des create ou des update. Dans 90% des cas, c’est mega pratique
mais
bizarrement aucune option n’a ete developpee pour eviter la sauvegarde
automatique. J’ai eu beau cherche avec mon ami google, personne n’a de
soluce ou semble se poser la question.
- Validation des associations
Ce qui est interessant avec les loggers, c’est que l’on peut voir
comment se
comporte RoR. Et j’ai trouve un truc vachement interessant. Reprenons
mon
premier exemple et virons la deuxieme association par exemple.
Imaginons que le model Image possede une validation tres poussee (genre
calcul pour savoir si les dimensions sont exactes)
On cree ensuite un controller (+ action) avec la vue pour la creation a
la
fois d’un Content et de la banner associee (donc de type image).
1er test: Content et Image sont valides.
Resultat: Pas de probleme, le tout est sauvegarde. No souci.
On remarque juste dans les logs, que la validation de la banner s’est
faite
APRES la sauvegarde du Content. Bizarre.
2eme test: Content est valide mais pas Image.
Resultat: Aucun message d’erreur n’est affiche mais banner n’a pas ete
sauvegardee (create ou update peu importe).
C’est chiant ! Pourtant dans les logs, on a bien vu que la validation
avait
eu lieu mais cette conne s’est faite apres celle de Content. C’est pas
de
chance. En parcourant l’API, on tombe sur la methode
“validates_associated”
qui semble repondre a nos besoins. Cool, mettons la dans notre modele
Content.
3eme test: Content est valide mais pas Image. “validates_associated”
dans
Content.
Resultat: Youpi ca marche, on a un beau message d’erreur (banner is
invalid). Content n’a pas ete sauvegarde. “So far so good”.
Un petit detail nous gene, en fait on aurait du avoir plusieurs erreurs
pour
la banner or une seule (generale) a ete remontee. Dommage.
En regardant, un peu plus dans les logs, on s’apercoit que la validation
de
banner a ete faite 2 FOIS: une fois par validates_associated et l’autre
fois
avant de sauvegarder banner. C’est nul
Conclusion: la double validation n’est pas genante car l’integrite des
donnees est conservee (heureusement !) mais il est evident que cela
ralentit
le serveur surtout si la validation d’un objet associe prend bcp de
ressource (je pense au traitement d’images par exemple). Il n’y a pas
veritablement de work around (enfin pas a ma connaissance), on peut
bidouiller (ce que j’ai fait) mais la solution reste bancale.
Conclusion Generale: sur le coup, j’avoue avoir ete decu un petit peu
par
RoR (pas par Ruby !). Je suis sur que certains d’entre vous sont tombes
sur
ce genre de probleme. J’aimerai bcp avoir vos avis.
Bonne soiree.
Did