Tester si la suppression d'un enregistrement est possible dans la BDD
samedi 01 décembre 2007 à 00:47 :: Prado :: #54 :: rss
Il est parfois utile et plus rapide de tester si la suppression d'un enregistrement est possible plutôt que de chercher s'il existe des relations ou non à cet enregistrement.
Supposons que nous avons deux tables, une représentant des articles et une autre des catégories. On établit une simple relation 1:n entre les deux tables 1 catégorie pouvant avoir plusieurs articles (ça marche aussi avec une relation n:m ou autre...).
Maintenant on imagine que nous voulons différencier l'affichage des catégories pouvant être supprimées et celles ne le pouvant pas car des articles leur sont rattachés.
Le premier réflexe et ce que font la plupart des développeurs c'est de regarder pour chaque catégorie combien d'enregistrements d'articles on trouve.
Pourtant, le plus simple est encore de tester si on peut supprimer la catégorie, et si des articles y sont lié, et bien on nous empêchera la suppression. Et plus le nombre d'articles sera grandissant, plus cette méthode sera préférable car certainement plus rapide. Bien que cela demande à être vérifier. Si quelqu'un possède des chiffres ou veut se lancer dans une petite expérience... j'attends de vos nouvelles
L'idée donc pour faire ça avec Prado est de faire la suppression dans une transaction et voir si ça marche ou pas, et dans tous les cas, faire un rollback.
Je rappel que Prado (version >= 3.1.x) dans notre cas utilise PDO et que la solution que je propose devrait par conséquent fonctionner avec différents SGBD et même d'autres langages que PHP
Pour ma part j'utilise ça de façon classique avec l'ensemble Ubuntu + Apache 2 + PHP 5.2 + MySQL 5 + Prado 3.1.1
Comme je n'ai trouvé que peu[1] de référence sur ce sujet j'ai décidé d'écrire moi-même ce petit article après avoir mis en place avec succès la manip tellement c'est simple
Avec les actives records, une transaction ce fait ainsi sous Prado (exemple pris tel quel dans le tuto de démarrage de Prado):
<?php $finder = UserRecord::finder(); $finder->DbConnection->Active=true; //open if necessary $transaction = $finder->DbConnection->beginTransaction(); try { $user = $finder->findByPk('admin'); $user->email = 'test@example.com'; //alter the $user object $user->save(); $transaction->commit(); } catch(Exception $e) // an exception is raised if a query fails { $transaction->rollBack(); } ?>
Une fois cet exemple adapté à ce que je dis plus haut ça donne le code suivant, qui fonctionne à merveille chez moi
<?php # [...] public function userCanBeDeleted($id){ $finder = UsersRecord::finder(); $transaction = $finder->DbConnection->beginTransaction(); try { $user = $finder->findByPk($id); $user->delete(); $transaction->rollBack(); $cr = true; } catch(Exception $e) { $transaction->rollBack(); $cr = false; } return $cr; } # [...] ?>
Voilà, j'espère qu'encore une fois ça rendra service à plusieurs d'entre vous
Notes
[1] Pour ne pas dire aucune...
Commentaires
1. Le vendredi 23 avril 2010 à 22:38, par Fred22
Ajouter un commentaire
Les commentaires pour ce billet sont fermés.