Lorsque j'ai besoin de relations de modèle, comment puis-je me protéger contre les erreurs?

StackOverflow https://stackoverflow.com/questions/803820

  •  03-07-2019
  •  | 
  •  

Question

J'ai une application avec beaucoup de relations de base de données qui dépendent les unes des autres pour pouvoir utiliser l'application avec succès. La charnière de l’application est un modèle appelé Schedule, mais le planning extraira des blocs, un employé, un JobTitle et une affectation (chaque bloc extraira également une affectation de la base de données). assembler un horaire des employés tout au long de la journée.

Lorsque j'ai créé l'application, j'ai beaucoup insisté sur les validations qui garantiraient que toutes les pièces devaient être en place avant que tout ne soit enregistré dans la base de données. Cela a fonctionné à merveille jusqu'à présent, et l'application est en direct depuis près de 6 mois et sert environ 150 000 demandes par mois, sans incident ni erreur. Jusqu'à la semaine dernière.

La semaine dernière, pendant que quelqu'un modifiait une planification, il semblait que la base de données était erronée et une planification a été enregistrée dans la base de données avec son affectation manquante. Étant donné que l'association est appelée dans chaque vue, chaque fois que cette planification a été appelée à partir de la base de données, l'application génère une erreur NoMethod pour un appel à nil.

Lorsque vous concevez une application comme je le disais, vous protégez-vous contre un éventuel échec de la base de données / des validations? Et si oui, comment vous défendez-vous par programme? Vérifiez-vous chaque relation pour vous assurer qu'elle n'est pas nulle avant de l'envoyer à la vue?

Je sais que cette question est inondée de généralité, et si je peux être plus précis dans ce que je veux dire, faites-le moi savoir dans les commentaires.

Était-ce utile?

La solution

Je recommanderais d'ajouter base de données appliquée contraintes de clé étrangère et incorporant d'importants groupes d'opérations dans des transactions .

S'il y a une clé étrangère entre Schedule et Assignment quelque part, une contrainte de clé étrangère appliquée par la base de données aurait empêché l'insertion erronée. De plus, si vous encapsulez l'action particulière dans une transaction, vous pouvez être sûr que le flux entier d'insertions / mises à jour / suppressions se produit ou échoue, revenant à un état de nettoyage.

Autres conseils

Outre vos validations et l'ajout de certaines contraintes de base de données, comme indiqué dans d'autres réponses, vous pouvez également exécuter un travail en arrière-plan qui balaye périodiquement la base de données à la recherche d'orphelins.

Lorsqu'il en trouve un, il le nettoie (si possible), le supprime ou le marque simplement inactif et vous envoie un courrier électronique afin que vous puissiez le consulter ultérieurement. Selon la quantité et la nature de vos données, une fois par minute, une fois par heure, une fois par jour ...

Ainsi, si de mauvaises données parviennent malgré les garanties que vous avez mises en place, vous les saurez le plus tôt possible.

Je vais discuter de la sagesse non conventionnelle à ce sujet. Les contraintes que vous décrivez n'appartiennent pas à la base de données, mais à votre code OO. Et ce n’est pas vrai que "la base de données a commis une erreur", c’est incontestablement vrai que l’application est ce qui a inséré des données incorrectement validées.

Lorsque vous commencez à vous attendre à ce que la base de données soit chargée de ces contrôles, vous insérez des règles de gestion dans le schéma. Au minimum, cela rend beaucoup plus difficile d’écrire des tests unitaires (c’est là que vous auriez probablement dû vous en prendre d’abord; mais c’est maintenant votre chance d’ajouter un autre test.)

Idéalement, vous devriez pouvoir remplacer le SGBDR par un autre magasin de données générique tout en conservant toute la logique fonctionnelle correctement active et inchangée aux emplacements appropriés. L’interface utilisateur ne devrait pas être beaucoup moins en contact direct avec les DAL.

Vous pouvez ajouter des contraintes de base de données supplémentaires si vous le souhaitez, mais cela doit être strictement comme une sauvegarde. Comme vous pouvez le constater, la gestion des erreurs structurelles dans la base de données (en particulier si l’interface utilisateur est impliquée) est beaucoup plus difficile.

Si c'est quelque chose qui doit être vrai pour que l'application fonctionne, c'est vraiment à quoi servent assert () . Je n’ai pratiquement jamais utilisé Ruby, mais j’imagine qu’il doit avoir ce concept. Utilisez-les pour imposer des conditions préalables à divers endroits de votre code. Cela, combiné à la désinfection et à la validation de vos entrées externes (utilisateur), devrait suffire à vous protéger. Je pense que si quelque chose ne va pas après cette vérification, votre application est autorisée à planter (de manière contrôlée, bien sûr).

Je doute que le problème que vous rencontrez soit un bogue dans votre base de données. Il est plus probable que vos validations aient été négligées dans vos validations.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top